26# include <bpf/libbpf.h>
45 char buf[INET6_ADDRSTRLEN]{};
65 c.
seen_at = std::chrono::system_clock::now();
81int ringbuf_callback(
void* ctx,
void* data,
size_t size)
83 if (!ctx || !data)
return 0;
92 auto* mon =
static_cast<EBPFMon*
>(ctx);
94 std::memcpy(&ev, data,
sizeof(ev));
103 std::lock_guard lk(mon->buf_mutex_);
104 mon->buf_.push_back(std::move(conn));
110 if (mon->buf_.size() > 8192)
111 mon->buf_.erase(mon->buf_.begin(),
112 mon->buf_.begin() + (mon->buf_.size() - 8192));
122 libbpf_set_strict_mode(LIBBPF_STRICT_ALL);
124 libbpf_set_print([](
enum libbpf_print_level level,
125 const char* fmt, va_list args) ->
int {
127 vsnprintf(buf,
sizeof(buf), fmt, args);
129 if (level == LIBBPF_WARN) l.warning(std::string(
"[libbpf] ") + buf);
130 else if (level == LIBBPF_INFO) l.info(std::string(
"[libbpf] ") + buf);
131 else l.debug(std::string(
"[libbpf] ") + buf);
136 struct bpf_object_open_opts opts{};
137 opts.sz =
sizeof(opts);
138 struct bpf_object* obj = bpf_object__open_file(obj_path.c_str(), &opts);
139 if (!obj || libbpf_get_error(obj)) {
140 log.warning(
"EBPFMon: impossibile aprire " + obj_path +
141 " — eBPF disabilitato");
146 if (bpf_object__load(obj) != 0) {
147 log.warning(
"EBPFMon: bpf_object__load fallito — "
148 "kernel BTF disponibile? CAP_BPF presente?");
149 bpf_object__close(obj);
166 struct bpf_program* prog =
nullptr;
167 bpf_object__for_each_program(prog, obj) {
169 const char* name = bpf_program__name(prog);
170 const char* sect = bpf_program__section_name(prog);
172 struct bpf_link* lnk = bpf_program__attach(prog);
173 if (!lnk || libbpf_get_error(lnk)) {
174 log.warning(std::string(
"EBPFMon: attach fallito per ")
175 + (name ? name :
"?")
176 +
" (sezione " + (sect ? sect :
"?") +
") — "
177 +
"il simbolo potrebbe non esistere su questo kernel");
182 log.debug(std::string(
"EBPFMon: attached ")
183 + (name ? name :
"?")
184 +
" (" + (sect ? sect :
"?") +
")");
188 log.warning(
"EBPFMon: nessun programma attaccato — disabilito eBPF");
189 bpf_object__close(obj);
195 struct bpf_map* rb_map =
196 bpf_object__find_map_by_name(obj,
"bsc_events");
198 log.warning(
"EBPFMon: mappa 'bsc_events' non trovata");
199 for (
auto* l :
links_) bpf_link__destroy(
static_cast<struct bpf_link*
>(l));
201 bpf_object__close(obj);
206 struct ring_buffer* rb =
209 log.warning(
"EBPFMon: ring_buffer__new fallito");
210 for (
auto* l :
links_) bpf_link__destroy(
static_cast<struct bpf_link*
>(l));
212 bpf_object__close(obj);
223 log.info(
"EBPFMon: attivo — " + std::to_string(attached) +
"/" +
224 std::to_string(total) +
" probe agganciati "
225 "(tracepoint + kprobes TCP/UDP)");
237 ring_buffer__free(
static_cast<struct ring_buffer*
>(
ring_buf_));
241 if (l) bpf_link__destroy(
static_cast<struct bpf_link*
>(l));
245 bpf_object__close(
static_cast<struct bpf_object*
>(
bpf_obj_));
259 auto* rb =
static_cast<struct ring_buffer*
>(
ring_buf_);
260 while (!
stop_.load()) {
261 ring_buffer__poll(rb, 20 );
267 std::vector<bsc::model::Connection> out;
280 "EBPFMon: compilato senza libbpf — eBPF non disponibile");
friend int ringbuf_callback(void *ctx, void *data, size_t size)
std::vector< bsc::model::Connection > drain()
bool start(const std::string &obj_path="/usr/lib/bastionguard-sc/bsc_ebpf.o")
std::vector< void * > links_
std::vector< bsc::model::Connection > buf_
void info(const std::string &msg)
static Logger & instance()
bsc::model::Connection event_to_connection(const ConnEvent &ev)
std::chrono::system_clock::time_point seen_at