This commit is contained in:
gbucchino 2025-02-06 15:25:34 +01:00
parent 0872e2a6a7
commit 1449cc961d
7 changed files with 11 additions and 23 deletions

@ -7,7 +7,7 @@ LIBS=-L../libbpf/src -l:libbpf.a -lelf -lz
all: dns-trace.ebpf.o dns-trace
dns-trace.ebpf.o: src/dns-trace.ebpf.c
$(CL) -g -O2 -target bpf -D __TARGET_ARCH_x86_64 -D __BPF_TRACING__ -L../libbpf/src -l:libbpf.a -c src/dns-trace.ebpf.c -o src/dns-trace.ebpf.o
$(CL) -Wall -g -O2 -target bpf -D __TARGET_ARCH_x86_64 -D __BPF_TRACING__ -L../libbpf/src -l:libbpf.a -c src/dns-trace.ebpf.c -o src/dns-trace.ebpf.o
dns-trace: src/dns-trace.c
$(GCC) $(CFLAGS) src/dns-trace.c -o dns-trace $(LIBS)

BIN
dns-trace

Binary file not shown.

@ -3,4 +3,4 @@
#sudo bpftool btf dump file /sys/kernel/btf/vmlinux format c > src/vmlinux.h
make clean
make all && sudo ./dns-trace -i wlp0s20f3
make all && sudo ./dns-trace -i enx98e743c667fc

@ -32,18 +32,18 @@ struct event {
unsigned char buf[MAX_UDP_PAYLOAD]; // On stocke la data au format size + data
};
struct query_section{
/*struct query_section{
char qname[QNAME_SIZE];
size_t qname_len;
uint16_t class;
uint16_t type;
};
};*/
struct dns_answer {
/*struct dns_answer {
char data[512];
uint16_t class;
uint16_t type;
uint32_t ttl;
};
};*/
#endif

@ -305,7 +305,6 @@ int handle_event(void *ctx, void *data, size_t data_sz){
printf("%s\t", s_type);
free(s_type);
if (type == 1) { // -> A
uint32_t ip = s_event->buf[pos] + (s_event->buf[pos+1] << 8) + (s_event->buf[pos+2] << 16) + (s_event->buf[pos+3] << 24);
printf("%s %5d", inet_ntoa(*(struct in_addr*)&ip), ttl);
@ -321,7 +320,7 @@ int handle_event(void *ctx, void *data, size_t data_sz){
if (i % 2 == 0)
printf("%x", s_event->buf[pos + p++]);
else{
if (i<size - 1)
if (i < (size - 1))
printf("%x:", s_event->buf[pos + p++]);
else
printf("%x", s_event->buf[pos + p++]);

@ -47,7 +47,7 @@ static size_t get_labels(struct __sk_buff *skb, size_t offset, struct event *s_e
while (c != '\0') {
bpf_skb_load_bytes(skb, offset + pos++, &c, 1);
if(c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z')
if((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'))
s_event->qname[qname_len] = c;
else if(c >= '0' && c <= '9')
s_event->qname[qname_len] = c;
@ -117,7 +117,7 @@ static unsigned int get_answer(struct __sk_buff *skb, struct event *s_event, siz
return 0;
bpf_skb_load_bytes(skb, tlen, s_event->buf + offset, sizeof(uint16_t));
uint16_t type = s_event->buf[0] + (s_event->buf[1] << 8);
//uint16_t type = s_event->buf[0] + (s_event->buf[1] << 8);
tlen += 2;
if ((offset += 2) >= MAX_UDP_PAYLOAD - sizeof(uint16_t))
return 0;
@ -145,7 +145,6 @@ static unsigned int get_answer(struct __sk_buff *skb, struct event *s_event, siz
return 0;
tlen += 2;
uint32_t data;
if (s_event->type == 1) { // -> A
bpf_skb_load_bytes(skb, tlen, s_event->buf + offset, sizeof(uint32_t));
}
@ -165,13 +164,13 @@ static unsigned int get_answer(struct __sk_buff *skb, struct event *s_event, siz
static int dnsquery(struct __sk_buff *skb, struct ethhdr eth, struct iphdr ip, struct udphdr udp, int dport, int sport){
struct event *s_event;
struct dnshdr dns = {0};
struct query_section dquery = {0};
/* Get DNS header */
bpf_skb_load_bytes(skb, sizeof(struct ethhdr) + sizeof(struct iphdr) + sizeof(struct udphdr), &dns, sizeof(struct dnshdr));
// Check OpCode
uint16_t qr = ntohs(dns.flags) & 0xF000; // Get the QR code: 0 -> query, 1 -> response
/* If it's not a query, we do not continue */
if(qr != 0x0)
return 0;
@ -192,7 +191,7 @@ static int dnsquery(struct __sk_buff *skb, struct ethhdr eth, struct iphdr ip, s
/* Get the query section */
uint8_t tlen = sizeof(struct ethhdr) + sizeof(struct iphdr) + sizeof(struct udphdr);
size_t query_len = get_query_section(skb, s_event, tlen);
get_query_section(skb, s_event, tlen);
// https://docs.cilium.io/en/stable/reference-guides/bpf/progtypes/
s_event->dport = dport;
@ -204,7 +203,6 @@ static int dnsquery(struct __sk_buff *skb, struct ethhdr eth, struct iphdr ip, s
}
static void dnsanswer_old(struct __sk_buff *skb, struct iphdr ip, struct udphdr udp, int dport, int sport){
char buf[256] = {0}; // Max dns domain name length
//__u16 udplen = 0U;
// Check with ip.len
@ -247,7 +245,6 @@ static void dnsanswer_old(struct __sk_buff *skb, struct iphdr ip, struct udphdr
static void dnsanswer(struct __sk_buff *skb, struct iphdr ip, struct udphdr udp, int dport, int sport){
struct event *s_event;
struct dnshdr dns;
uint16_t tid = 0U;
uint32_t offset = sizeof(struct ethhdr) + sizeof(struct iphdr) + sizeof(struct udphdr);
size_t tlen = ntohs(udp.len);
int index = 0;
@ -255,8 +252,6 @@ static void dnsanswer(struct __sk_buff *skb, struct iphdr ip, struct udphdr udp,
if (tlen < 0 || tlen >= 256)
return;
bpf_printk("udp len: %d", tlen);
// Load dns header
if (bpf_skb_load_bytes(skb, offset, &dns, sizeof(struct dnshdr)) < 0)
return;
@ -294,20 +289,14 @@ static void dnsanswer(struct __sk_buff *skb, struct iphdr ip, struct udphdr udp,
return;
}
/*if (ans > 0){
s_event->numAns = ans;
}*/
s_event->numAns = ans;
// Load query and answer
/*
* Load query and answers
* It's a little dirty to do that, to load byte by byte,
* otherwise, I have an issue with the eBPF verifier
*/
offset += sizeof(struct dnshdr) + query_len;
//offset += 2; // We bypass message compression
while (index < tlen){
bpf_skb_load_bytes(skb, offset + index, s_event->buf + index, 1);
index++;

Binary file not shown.