1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | sockex1_kern.o: file format ELF64-BPF Disassembly of section socket1: bpf_prog1: 0: bf 16 00 00 00 00 00 00 r6 = r1 1: 30 00 00 00 17 00 00 00 r0 = *(u8 *)skb[23] 2: 63 0a fc ff 00 00 00 00 *(u32 *)(r10 - 4) = r0 3: 61 61 04 00 00 00 00 00 r1 = *(u32 *)(r6 + 4) 4: 55 01 08 00 04 00 00 00 if r1 != 4 goto 8 5: bf a2 00 00 00 00 00 00 r2 = r10 6: 07 02 00 00 fc ff ff ff r2 += -4 7: 18 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 r1 = 0ll 9: 85 00 00 00 01 00 00 00 call 1 10: 15 00 02 00 00 00 00 00 if r0 == 0 goto 2 11: 61 61 00 00 00 00 00 00 r1 = *(u32 *)(r6 + 0) 12: db 10 00 00 00 00 00 00 lock *(u64 *)(r0 + 0) += r1 LBB0_3: 13: b7 00 00 00 00 00 00 00 r0 = 0 14: 95 00 00 00 00 00 00 00 exit |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | from bcc import BPF # 和清单 2 一样,篇幅所限,这里只贴一部分源码,完全版请移步 interface="ens160" # BCC 可以接受直接将 BPF 代码嵌入 python code 之中 # 为了方便展示笔者使用了这一功能 # 注意:prog 中的中文注释是由于笔者需要写作之故加入,如果读者想尝试运行这段代码, # 则请将中文全部删除,因为目前 BCC 还不支持在内嵌 C 代码中使用中文注释 prog = """ #include <net/sock.h> #include <bcc/proto.h> // BCC 中专门为 map 定义了一系列的宏,以方便使用 // 宏中的 struct 下还定义了相应的函数,让开发者可以如 C++一般操作 map // 这里笔者定义了一个 array 类型的 map,名为 my_map1 BPF_ARRAY(my_map1, long); // BCC 下的 BPF 程序中不再需要定义把函数或变量专门放置于某个 section 下了 int bpf_prog1(struct __sk_buff *skb) { // …… struct ethernet_t *eth = cursor_advance(cursor, sizeof(*eth)); // …… struct ip_t *ip = cursor_advance(cursor, sizeof(*ip)); int index = ip->nextp; long zero = 0; // BCC 下的 bpf 书写还是有很多坑的 // 例如,这里如果不去定义一个局部变量 zero, // 而是直接用常量 0 作为 lookup_or_init()的变量就会报错 // map 类下的各个方法的具体细节可以参照 reference_guide.md value = my_map1.lookup_or_init(&index, &zero); if (value) __sync_fetch_and_add(value, skb->len); return 0; } """ bpf = BPF(text=prog, debug = 0) # 注入 bpf_prog1 函数 function = bpf.load_func("bpf_prog1", BPF.SOCKET_FILTER) # 这是一段 SOCKET_FILTER 类型的 BPF,所以需要挂载到某一个 interface 上 BPF.attach_raw_socket(function, interface) # 利用 map 机制获取进出 interface 的各个协议的报文总长 bpf_map = bpf["my_map1"] while 1: print ("TCP : {}, UDP : {}, ICMP: {}".format( bpf_map[socket.IPPROTO_TCP].value, # … |
欢迎光临 电子技术论坛_中国专业的电子工程师学习交流社区-中电网技术论坛 (http://bbs.eccn.com/) | Powered by Discuz! 7.0.0 |