src/main.bpf.c:
Код: Выделить всё
#include "../vmlinux.h"
#include
#include
#include
#include
#include "../include/omega.h"
#define ETH_P_IP 0x0800
/*
* NOTES:
* __builtin_memcpy HAS TO BE USED BEFORE bpf_ringbuf_submit otherwise it will generate an error!
*/
struct {
__uint(type, BPF_MAP_TYPE_RINGBUF);
__uint(max_entries, 256 * 1024);
} rb SEC(".maps");
SEC("xdp")
int xdp_packet_filter(struct xdp_md *ctx) {
struct packet_evt *evt = {0};
evt = bpf_ringbuf_reserve(&rb, sizeof(*evt), 0);
if (!evt) {
return XDP_PASS;
}
void *data = (void *)(long)ctx->data;
void *data_end = (void *)(long)ctx->data_end;
struct ethhdr *eth = data;
if ((void *)(eth + 1) > data_end) {
goto failure;
}
if (eth->h_proto != bpf_htons(ETH_P_IP)) {
goto failure;
}
struct iphdr *ip = data + sizeof(struct ethhdr);
if ((void *)(ip + 1) > data_end) {
goto failure;
}
if (ip->protocol == IPPROTO_UDP) {
struct udphdr *udp = (void *)ip + sizeof(struct iphdr);
if ((void *)(udp + 1) > data_end) {
goto failure;
}
__u16 src_port = bpf_ntohs(udp->source);
__u16 dest_port = bpf_ntohs(udp->dest);
if (evt) {
evt->src_ip = ip->saddr;
evt->dst_ip = ip->daddr;
evt->src_port = src_port;
evt->dst_port = dest_port;
bpf_printk("Submitting Event: SRC IP: %x DST IP: %x SRC PORT: %d DST PORT: %d\n",
evt->src_ip, evt->dst_ip, evt->src_port, evt->dst_port);
//bpf_printk("TCP packet from %x:%d to %x:%d\n",
//ip->saddr, src_port, ip->daddr, dest_port);
} else {
bpf_printk("Ring buffer reservation failed\n");
goto failure;
}
//PACKET FROM TO
//bpf_printk("UDP|%x:%d|%x:%d\n",
// ip->saddr, src_port, ip->daddr, dest_port);
} else if (ip->protocol == IPPROTO_TCP) {
struct tcphdr *tcp = (void *)ip + sizeof(struct iphdr);
if ((void *)(tcp + 1) > data_end) {
goto failure;
}
__u16 src_port = bpf_ntohs(tcp->source);
__u16 dest_port = bpf_ntohs(tcp->dest);
if (evt) {
evt->src_ip = ip->saddr;
evt->dst_ip = ip->daddr;
evt->src_port = src_port;
evt->dst_port = dest_port;
bpf_printk("Submitting Event: SRC IP: %x DST IP: %x SRC PORT: %d DST PORT: %d\n",
evt->src_ip, evt->dst_ip, evt->src_port, evt->dst_port);
//bpf_printk("TCP packet from %x:%d to %x:%d\n",
//ip->saddr, src_port, ip->daddr, dest_port);
} else {
bpf_printk("Ring buffer reservation failed\n");
goto failure;
}
// PACKET FROM TO
// bpf_printk("TCP|%x:%d|%x:%d\n",
// ip->saddr, src_port, ip->daddr, dest_port);
}
bpf_ringbuf_submit(evt, 0);
bpf_printk("Evt submit done!\n");
return XDP_PASS;
failure:
bpf_printk("Failure!\n");
bpf_ringbuf_discard(evt, 0);
return XDP_PASS;
}
char LICENSE[] SEC("license") = "GPL";
Код: Выделить всё
#ifndef __OMEGA_H__
#define __OMEGA_H__
#define MAX_EVENT_LEN 24
struct packet_evt {
__u32 src_ip;
__u32 dst_ip;
__u16 src_port;
__u16 dst_port;
};
#endif // __OMEGA_H__
Код: Выделить всё
#include
#include
#include
#include
#include
#include
#include
#include "../omega.skel.h"
#include "../include/omega.h"
static volatile int stop = 0;
static void bump_memlock_rlimit(void) {
struct rlimit rlim_new = {
.rlim_cur = RLIM_INFINITY,
.rlim_max = RLIM_INFINITY,
};
if (setrlimit(RLIMIT_MEMLOCK, &rlim_new)) {
fprintf(stderr, "Failed to increase RLIMIT_MEMLOCK limit!\n");
exit(1);
}
}
void handle_signal(int sig) {
stop = 1;
}
static int handle_evt(void *ctx, void *data, size_t sz) {
const struct packet_evt *evt = data;
fprintf(stdout, "Received Event: SRC IP: %u DST IP: %u SRC PORT: %u DST PORT: %u\n",
evt->src_ip, evt->dst_ip, evt->src_port, evt->dst_port);
fflush(stdout);
return 0;
}
int main(void) {
struct omega *skel = NULL;
struct ring_buffer *rb = NULL;
signal(SIGINT, handle_signal);
signal(SIGTERM, handle_signal);
// Increase rlimit for BPF memory lock
bump_memlock_rlimit();
skel = omega__open();
if (!skel) {
fprintf(stderr, "Failed to open BPF skeleton\n");
return 1;
}
if (omega__load(skel)) {
fprintf(stderr, "Failed to load BPF skeleton\n");
omega__destroy(skel);
return 1;
}
if (omega__attach(skel)) {
fprintf(stderr, "Failed to attach BPF skeleton\n");
omega__destroy(skel);
return 1;
}
// Set up ring buffer
int rb_fd = bpf_map__fd(skel->maps.rb);
if (rb_fd < 0) {
fprintf(stderr, "Failed to get ring buffer FD\n");
omega__destroy(skel);
return 1;
}
rb = ring_buffer__new(rb_fd, handle_evt, NULL, NULL);
if (!rb) {
fprintf(stderr, "Failed to create ring buffer\n");
omega__destroy(skel);
return 1;
}
printf("Ring buffer successfully created. Waiting for events...\n");
while (!stop) {
int err = ring_buffer__poll(rb, 1000);
if (err < 0) {
fprintf(stderr, "Error polling ring buffer: %d\n", err);
break;
}
}
printf("Cleaning up...\n");
ring_buffer__free(rb);
omega__destroy(skel);
return 0;
}
bpf_trace_printk: Событие отправки: SRC IP: 108CA203 DST IP: 6D00A8C0 SRC Port: 443 DST Port: 55938 < /p>
Также, когда я запускаю погрузчик, я получаю.
Ring Buffer успешно создан. В ожидании событий ... < /p>
Также он печатает EVT отправить! Таким образом, код наверняка приходит в Rinbuf_submit. < /p>
Я не уверен, что может быть потенциальным исправлением или следующими шагами отладки. Я предполагаю, что harder_evt не может быть вызван, но опять же, очень сомневаюсь в этом. есть.
Подробнее здесь: https://stackoverflow.com/questions/794 ... -populated