1 #include "vmlinux.h"
2 #include <bpf/bpf_helpers.h>
3 #include <bpf/bpf_tracing.h>
4 #include <bpf/bpf_core_read.h>
5 #include "conn.h"
6
7 struct {
8 __uint(type, BPF_MAP_TYPE_RINGBUF);
9 __uint(max_entries, 256 * 1024);
10 } conns SEC(".maps");
11
12 struct {
13 __uint(type, BPF_MAP_TYPE_HASH);
14 __uint(max_entries, 8192);
15 __type(key, int);
16 __type(value, void*);
17 } accept_addr SEC(".maps");
18
19
20 struct syscalls_enter_connect_args {
21 char _[24];
22 struct sockaddr *addr;
23 };
24 struct syscalls_enter_accept_args {
25 char _[24];
26 struct sockaddr *addr;
27 };
28
29 SEC("tp/syscalls/sys_enter_connect")
trace_enter_connect(struct syscalls_enter_connect_args * ctx)30 int trace_enter_connect(struct syscalls_enter_connect_args *ctx)
31 {
32 struct conn_event *event;
33 event = bpf_ringbuf_reserve(&conns, sizeof(*event), 0);
34 if (!event) return 0;
35 event->pid = bpf_get_current_pid_tgid() >> 32;
36 if (bpf_probe_read_user(&event->addr, sizeof(event->addr), (void*)(ctx->addr))) {
37 bpf_ringbuf_discard(event, 0);
38 } else bpf_ringbuf_submit(event, 0);
39 return 0;
40 }
41
42 SEC("tp/syscalls/sys_enter_accept")
trace_enter_accept(struct syscalls_enter_accept_args * ctx)43 int trace_enter_accept(struct syscalls_enter_accept_args *ctx)
44 {
45 int pid = bpf_get_current_pid_tgid() >> 32;
46 void *addr = (void*)(ctx->addr);
47 bpf_map_update_elem(&accept_addr, &pid, &addr, BPF_ANY);
48 return 0;
49 }
50
51 SEC("tp/syscalls/sys_exit_accept")
trace_exit_accept(void * ctx)52 int trace_exit_accept(void *ctx)
53 {
54 int pid = bpf_get_current_pid_tgid() >> 32;
55 void **paddr = (void**)bpf_map_lookup_elem(&accept_addr, &pid);
56 if (paddr) {
57 bpf_map_delete_elem(&accept_addr, &pid);
58 struct conn_event *event;
59 event = bpf_ringbuf_reserve(&conns, sizeof(*event), 0);
60 if (!event) return 0;
61 event->pid = -pid;
62 long r=bpf_probe_read_user(&(event->addr), sizeof(event->addr), *paddr);
63 if (r) {
64 // bpf_printk("fail to read user space value %lld\n", r);
65 bpf_ringbuf_discard(event, 0);
66 } else bpf_ringbuf_submit(event, 0);
67 }
68 return 0;
69 }
70
71 SEC("tp/syscalls/sys_enter_accept4")
trace_enter_accept4(struct syscalls_enter_accept_args * ctx)72 int trace_enter_accept4(struct syscalls_enter_accept_args *ctx)
73 {
74 int pid = bpf_get_current_pid_tgid() >> 32;
75 void *addr = (void*)(ctx->addr);
76 bpf_map_update_elem(&accept_addr, &pid, &addr, BPF_ANY);
77 return 0;
78 }
79
80 SEC("tp/syscalls/sys_exit_accept4")
trace_exit_accept4(void * ctx)81 int trace_exit_accept4(void *ctx)
82 {
83 int pid = bpf_get_current_pid_tgid() >> 32;
84 void **paddr = (void**)bpf_map_lookup_elem(&accept_addr, &pid);
85 if (paddr) {
86 bpf_map_delete_elem(&accept_addr, &pid);
87 struct conn_event *event;
88 event = bpf_ringbuf_reserve(&conns, sizeof(*event), 0);
89 if (!event) return 0;
90 event->pid = -pid;
91 long r=bpf_probe_read_user(&(event->addr), sizeof(event->addr), *paddr);
92 if (r) {
93 // bpf_printk("fail to read user space value %lld\n", r);
94 bpf_ringbuf_discard(event, 0);
95 } else bpf_ringbuf_submit(event, 0);
96 }
97 return 0;
98 }
99
100 char _license[] SEC("license") = "GPL";
101