/* uprobe_apache.c — Capture HTTP depuis Apache httpd via recvfrom * * Identique à nginx : sys_enter_recvfrom + kretprobe __x64_sys_recvfrom * * ============================================================================ */ #include "vmlinux.h" #include #include #include "bpf_types.h" #define MAX_RECV_SIZE 4096 struct recvfrom_args { __s32 sockfd; __u64 buf_ptr; __u64 len; __s64 flags; } __attribute__((packed)); /* sys_enter_recvfrom - identique à nginx */ SEC("tp/syscalls/sys_enter_recvfrom") int tp_sys_enter_recvfrom(struct trace_event_raw_sys_enter *ctx) { __u64 pid_tgid = bpf_get_current_pid_tgid(); __u32 pid = pid_tgid >> 32; __u8 *enabled = bpf_map_lookup_elem(&apache_http_pid_map, &pid); if (!enabled || *enabled == 0) { return 0; } struct recvfrom_args args = {}; args.sockfd = (__s32)ctx->args[0]; args.buf_ptr = (__u64)ctx->args[1]; args.len = (__u64)ctx->args[2]; args.flags = (__s64)ctx->args[3]; bpf_map_update_elem(&apache_http_recv_args_map, &pid_tgid, &args, BPF_ANY); return 0; } /* kretprobe __x64_sys_recvfrom - identique à nginx */ SEC("kretprobe/__x64_sys_recvfrom") int kretprobe_sys_exit_recvfrom(struct pt_regs *ctx) { __u64 pid_tgid = bpf_get_current_pid_tgid(); __u32 pid = pid_tgid >> 32; __u8 *enabled = bpf_map_lookup_elem(&apache_http_pid_map, &pid); if (!enabled || *enabled == 0) { return 0; } struct recvfrom_args *args = bpf_map_lookup_elem(&apache_http_recv_args_map, &pid_tgid); if (!args) { return 0; } long retval = PT_REGS_RC(ctx); if (retval <= 0) { bpf_map_delete_elem(&apache_http_recv_args_map, &pid_tgid); return 0; } __u32 data_len = retval; if (data_len > MAX_RECV_SIZE) data_len = MAX_RECV_SIZE; __u32 zero = 0; struct apache_http_event *e = bpf_map_lookup_elem(&__apache_buf, &zero); if (!e) { bpf_map_delete_elem(&apache_http_recv_args_map, &pid_tgid); return 0; } e->pid_tgid = pid_tgid; e->fd = args->sockfd; e->src_ip = 0; e->src_port = 0; e->timestamp_ns = bpf_ktime_get_ns(); e->method_len = 0; e->uri_len = 0; e->query_len = 0; e->body_len = 0; e->data_len = 0; if (data_len > 0) { __u32 copy_len = data_len; if (copy_len > sizeof(e->data)) copy_len = sizeof(e->data); bpf_probe_read_user(e->data, copy_len, (void *)args->buf_ptr); e->data_len = copy_len; } bpf_perf_event_output(ctx, &pb_apache_http, BPF_F_CURRENT_CPU, e, sizeof(*e)); bpf_map_delete_elem(&apache_http_recv_args_map, &pid_tgid); return 0; } char LICENSE[] SEC("license") = "GPL";