如何通过ebpf从tcp_probe跟踪点获取有效负载数据?

问题描述 投票:0回答:1

我需要读取TCP数据包的有效负载。以下代码始终打印空有效负载,即使有效负载大小大于零。我做错了什么?

#include "vmlinux.h"
#include <bpf/bpf_helpers.h>

struct data_t {
      unsigned pid;
      unsigned uid;
      unsigned short sport;
      unsigned short dport;
      int payloadSize;
      char payload[256];
};

SEC("tp/tcp/tcp_probe")
int trace_http2_headers(struct trace_event_raw_tcp_probe *ctx) {
   struct data_t data = {};
   data.pid = bpf_get_current_pid_tgid() >> 32;
   data.uid = bpf_get_current_uid_gid() >> 32;
  bpf_probe_read(&data.sport, sizeof(data.sport),&ctx->sport);
  bpf_probe_read(&data.dport, sizeof(data.dport),&ctx->dport);
  bpf_probe_read(&data.payloadSize, sizeof(data.payloadSize),&ctx->data_len);

  bpf_probe_read(&data.payload, 256 * sizeof(char), ctx->__data);
    
 if (data.payloadSize ==0) return 0;
 bpf_printk("PAYLOAD: %.*s\n", data.payloadSize, data.payload);

  return 0;
}

char LICENSE[] SEC("license") = "Dual BSD/GPL"; 
ebpf
1个回答
0
投票

TL;DR. 您的代码可能没有显示任何内容,因为

%.*s
帮助程序不支持语法
bpf_trace_printk


来源

来自文档

fmt 支持的转换说明符类似,但比 printk() 的限制更多。它们是

%d
%i
%u
%x
%ld
%li
%lu
%lx
%lld
%lli
%llu
,
%llx
%p
。没有可用的修饰符(字段大小、用零填充等),如果遇到未知说明符,助手将返回
%s
(但不打印任何内容)。


测试

如果我使用密件抄送运行以下程序:

-EINVAL

然后 bcc 警告我有关说明符不正确的信息,然后第一个 printk 调用失败:

char payload[10] = "Tail-call"; int res = bpf_trace_printk("PAYLOAD: %.*s", payload); if (res < 0) { bpf_trace_printk("The first call to bpf_trace_printk failed."); } return 0;

© www.soinside.com 2019 - 2024. All rights reserved.