基於c語言的BPF程式

2021-10-06 17:57:37 字數 2953 閱讀 7521

當你在使用bpf程式時,你需要去指定哪種型別的程式在執行。型別將會告訴程式,你的**將在核心的哪個地方被執行。同時,它也會告訴bpf虛擬機器的verifier,哪種型別的bpf helper將會被允許使用。當你選擇了程式型別,你同時也選擇了你的**要實現的相關介面。該介面將確保你可以訪問你想要的資料、想要獲取的網路包等等。

bpf程式的編譯,一般使用llvm.llvm是一種genreal-purpose 的編譯器,llvm可以emit不同的位元組碼。在本章中,llvm將生成bpf的位元組碼,然後我們會load到核心的虛擬中。

核心提供了乙個系統呼叫,專門用於load bpf的程式,除了load bpf的程式,這個系統呼叫,還可以有一些其他的操作,後面我們會看到它的用法,接下來,我們來看下hello world:

#include #define sec(name) __attribute__((section(name), used))

static int (*bpf_trace_printk)(const char *fmt, int fmt_size,

...) = (void *)bpf_func_trace_printk;

sec("tracepoint/syscalls/sys_enter_execve")

int bpf_prog(void *ctx)

char _license sec("license") = "gpl";

編譯:

clang -o2 -target bpf -c bpf_program.c  -i /usr/include/x86_64-linux-gnu/ -o bpf_program.o
我們使用sec屬性,告訴bpf vm,我們想在什麼時候執行我們寫的這個程式。在上面的**中,我們指定在kernel呼叫到execve的時候,來呼叫我們自己寫的程式。即:sec中定義的是乙個tracepoints,是kernel預先定義好的,允許開發者,在這裡injet進去自己的**。那你可能會問,我怎麼知道都有哪些tracepoints呢?這個可以在/sys/kernel/debug/tracing/events/syscalls/這個目錄下找到系統預留的所有的tracepoints.

另外,我們需要使用指定gpl的協議。因為kernel本身就是gpl的。我們使用bpf_trace_printk來列印在核心中生成的日誌。當然你也可以通過/sys/kernel/debug/tracing/trace_pipe來檢視核心的日誌。

安裝需要的工具依賴

sudo apt update

sudo apt install build-essential git make libelf-dev clang strace tar bpfcc-tools linux-headers-$(uname -r) gcc-multilib

我們需要乙份原始碼來編譯libbpf

cd /tmp

git clone --depth 1 git:

可以將原始碼拷貝到/kernel-src目錄下,然後編譯libbpf

sudo mv ubuntu-bionic /kernel-src

cd /kernel-src/tools/lib/bpf

sudo make && sudo make install prefix=/usr/local

將編譯的結果移動到系統的library path

sudo mv /usr/local/lib64/libbpf.* /lib/x86_64-linux-gnu/
現在我們有了bpf的**,需要乙個程式把它load到核心中。

#include "bpf_load.h"

#include #include #include #include #include #include int main(int argc, char **ar**)

read_trace_pipe();

return 0;

}

makefile:

clang = clang

execable = monitor-exec

bpfcode = bpf_program

bpftools = /kernel-src/samples/bpf

bpfloader = $(bpftools)/bpf_load.c

ccinclude += -i/kernel-src/tools/testing/selftests/bpf

loadinclude += -i/kernel-src/samples/bpf

loadinclude += -i/kernel-src/tools/lib

loadinclude += -i/kernel-src/tools/perf

loadinclude += -i/kernel-src/tools/include

library_path = -l/usr/local/lib64

bpfso = -lbpf

.phony: clean $(clang) bpfload build

clean:

rm -f *.o *.so $(execable)

build: $ $

$(clang) -o2 -target bpf -c $(bpfcode:=.c) $(ccinclude) -o $

bpfload: build

clang -o $(execable) -lelf $(loadinclude) $(library_path) $(bpfso) \

$(bpfloader) loader.c

$(execable): bpfload

.default_goal := $(execable)

編譯完成後,執行可執行檔案。隨便執行個ls之類的,就可以看到hello world的輸出了。

基於C 語言的程式呼叫

由於葉綠素反演系統並不是我乙個人的成果,未經隊友們的同意,無法上傳相關 因此對c ae構建系統的相關介紹就到這裡,接下來為大家提供一些我初學c 時覺得比較有意思的 此篇文章為大家介紹下如何給予c 語言對程式進行巢狀呼叫。不長,也不難,但重在理解,本程式是基於vs的窗體實現,其布局如下,主要由乙個gr...

基於C語言的避障系統程式

基於c語言的避障小車程式 因為最近在做一些小專案,我就把我寫的程式分享給大家,一起學習 include include define uchar unsigned char define uint unsigned int sbit trig p3 0 sbit echo p3 3 sbit con...

基於C 的聊天程式

1.引言 1.1目的 編寫詳細設計說明書是軟體開發過程必不可少的部分,其目的是為了在完成需求分析說明書的基礎上完成需求分析說明規定的各項模組的具體實現的設計工作。1.2定義 套接字socket 網路上的兩個程式通過乙個雙向的通訊連線實現資料的交換,這個連線的一端稱為乙個socket。tcp協議 tc...