首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何用eBPF获取linux系统IP层数据包,并打印出来?

如何用eBPF获取linux系统IP层数据包,并打印出来?

提问于 2024-09-30 16:09:20
回答 0关注 0查看 4

我尝试用bcc获取到Linux系统IP层的数据包,写了下面这段代码

代码语言:txt
复制
from bcc import BPF
import ctypes as ct
import binascii

# 定义eBPF程序
bpf_code = """
#include <uapi/linux/bpf.h>
#include <linux/if_ether.h>
#include <linux/ip.h>

// 定义一个结构体来存储数据包内容
struct packet_data_t {
    u8 data[256];  // 假设最大数据包大小为512字节
    u32 len;      // 数据包长度
};

// 定义一个 BPF 数组映射
BPF_ARRAY(packet_map, struct packet_data_t, 1);  // 只存储一个元素

BPF_PERF_OUTPUT(events);

int packet_monitor(struct __sk_buff *skb) {
    struct packet_data_t data = { .len = 0 };  // 初始化 len 为 0
    u32 size = skb->len;
    u32 key = 0;  // 映射键

    // 确保数据包长度不超过我们定义的最大值,并且是非负数
    if (size > sizeof(data.data) || size < 0) {
        size = sizeof(data.data);
    }

    // 复制数据包内容到结构体中
    bpf_probe_read(&data.data, size, (void *)skb->data);
    data.len = size;

    // 将数据包内容存储到 BPF 数组映射中
    bpf_map_update_elem(&packet_map, &key, &data, BPF_ANY);

    // 将数据包内容发送到用户空间
    events.perf_submit_skb(skb, 0, &data, sizeof(data));

    return 0;
}
"""

# 加载BPF程序
b = BPF(text=bpf_code)

# 选择要监听的网络接口
interface = "ens33"  # 修改为你想要监听的接口名称
fn = b.load_func("packet_monitor", BPF.SOCKET_FILTER)
BPF.attach_raw_socket(fn, interface)

# 定义全局的 PacketData 结构体
class PacketData(ct.Structure):
    _fields_ = [
        ("data", ct.c_ubyte * 256),
        ("len", ct.c_uint32)
    ]

# 打印数据包的内容
def print_packet(cpu, data, size):
    event = ct.cast(data, ct.POINTER(PacketData)).contents
    packet_data = bytes(event.data[:event.len])
    hex_data = binascii.hexlify(packet_data).decode('utf-8')
    print(f"Packet length: {event.len} bytes")
    print(f"Packet content (hex): {hex_data}")

# 设置性能事件映射
b["events"].open_perf_buffer(print_packet)

# 初始化 BPF 数组映射
key = ct.c_uint32(0)
value = PacketData()
b["packet_map"][key] = value

print(f"Listening on {interface} for network packets... Hit Ctrl-C to stop.")
try:
    while True:
        b.perf_buffer_poll()
except KeyboardInterrupt:
    pass

但是会报错:

代码语言:txt
复制
bpf: Failed to load program: Invalid argument
unknown opcode 00
processed 0 insns (limit 1000000) max_states_per_insn 0 total_states 0 peak_states 0 mark_read 0

HINT: The 'unknown opcode' can happen if you reference a global or static variable, or data in read-only section. For example, 'char *p = "hello"' will result in p referencing a read-only section, and 'char p[] = "hello"' will have "hello" stored on the stack.

free(): invalid pointer
已放弃

不知道该怎么修改代码

回答

和开发者交流更多问题细节吧,去 写回答
相关文章

相似问题

相关问答用户
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档