我尝试用bcc获取到Linux系统IP层的数据包,写了下面这段代码
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
但是会报错:
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
已放弃
不知道该怎么修改代码
相似问题