c-获取带有eBPF跟踪点的HTTP请求和响应对



我正试图编写一个小程序,利用Linux的跟踪点sys_enter_recvfromsys_enter_sendto来显示系统上发生的HTTP请求和响应对。

首先,我定义了以下可以容纳HTTP对象的C结构,因此可以是请求或响应:

struct http_obj {
char comm[TASK_COMM_LEN];
int fd;
char *buff;
char *addr_data;
int size;
};

以下是我的跟踪点:

TRACEPOINT_PROBE(syscalls, sys_enter_recvfrom) {
return do_trace(args, args->fd, args->ubuf, args->addr);
}
TRACEPOINT_PROBE(syscalls, sys_enter_sendto){
return do_trace(args, args->fd, args->buff, args->addr);
}

以下是获取sys_enter_<syscall>跟踪点的args的函数:

static inline int do_trace(void* ctx, int fd, char *ubuf, struct sockaddr *addr)
{
// Built event for userland
struct http_obj evt = {};
bpf_get_current_comm(evt.comm, TASK_COMM_LEN);
evt.fd = fd;    
evt.buff = (char *) ubuf;
evt.size = sizeof(ubuf);
evt.addr_data = (char *) addr->sa_data;
// send to userland
http_obj.perf_submit(ctx, &evt, sizeof(evt));
return 0;
}

使用python中的bcc库,我只是打印发送到userland的字段的值。问题是缓冲区和事件地址总是空的。注意,字段是存在的,如果我们在/sys/kernel/debug/tracing/events/syscalls/sys_enter_recvfrom上执行cat,我们得到:

field:int __syscall_nr; offset:8;   size:4; signed:1;
field:int fd;   offset:16;  size:8; signed:0;
field:void __attribute__((user)) * buff;    offset:24;  size:8; signed:0;
field:size_t len;   offset:32;  size:8; signed:0;
field:unsigned int flags;   offset:40;  size:8; signed:0;
field:struct sockaddr __attribute__((user)) * addr; offset:48;  size:8; signed:0;
field:int addr_len; offset:56;  size:8; signed:0;

有什么建议吗?

问题是缓冲区和事件地址总是空的。

这并不意外,您看到的是通过系统调用传递给内核的来自用户空间的参数。缓冲区是空的,因为内核应该在运行该跟踪点之后将数据包内容写入缓冲区。地址是可选字段,根据recvfrom:的手册页允许为空

If  the  caller  is  not  interested in the source address, src_addr and addrlen should be specified as NULL.

我建议使用TC程序来检查交通

相关内容

  • 没有找到相关文章

最新更新