Update code

This commit is contained in:
gbucchino 2025-01-15 13:23:50 +01:00
parent fa6681095c
commit 5812b581e8
8 changed files with 123307 additions and 69979 deletions

BIN
dns-trace

Binary file not shown.

BIN
dns2.pcap Normal file

Binary file not shown.

BIN
dns3.pcap Normal file

Binary file not shown.

@ -1,6 +1,8 @@
#ifndef H_COMMON #ifndef H_COMMON
#define H_COMMON #define H_COMMON
#define QNAME_SIZE 128
struct dnshdr { struct dnshdr {
uint16_t transactionID; uint16_t transactionID;
uint16_t flags; uint16_t flags;
@ -11,17 +13,19 @@ struct dnshdr {
}; };
struct dns_query { struct dns_query {
char *name; char *name;
//char name[112]; uint16_t type;
uint16_t type; uint16_t class;
uint16_t class; // struct dns_query *next;
struct dns_query *next;
}; };
struct event { struct event {
uint32_t saddr;
int dport; int dport;
int sport; int sport;
char qname[QNAME_SIZE];
int class;
int type;
}; };
#endif #endif

@ -101,11 +101,93 @@ static int open_raw_sock(const char *name)
return sock; return sock;
} }
static void mapClass(const int class){
switch(class){
case 1:
printf("IN\n");
break;
case 2:
printf("CS\n");
break;
case 3:
printf("CH\n");
break;
case 4:
printf("HS\n");
break;
default:
printf("Unknown\n");
break;
}
}
static void mapType(const int type){
switch(type){
case 1:
printf("A");
break;
case 2:
printf("NS");
break;
case 3:
printf("MD");
break;
case 4:
printf("MF");
break;
case 5:
printf("CNAME");
break;
case 6:
printf("SOA");
break;
case 7:
printf("MB");
break;
case 8:
printf("MG");
break;
case 9:
printf("MR");
break;
case 10:
printf("NULL");
break;
case 11:
printf("WKS");
break;
case 12:
printf("PTR");
break;
case 13:
printf("HINFO");
break;
case 14:
printf("MINFO");
break;
case 15:
printf("MX");
break;
case 16:
printf("TXT");
break;
default:
printf("Unknown\n");
break;
}
printf("\n");
}
int handle_event(void *ctx, void *data, size_t data_sz){ int handle_event(void *ctx, void *data, size_t data_sz){
struct event *s_event = (struct event*)data; struct event *s_event = (struct event*)data;
printf("IP: %s\n", inet_ntoa(*(struct in_addr*)&s_event->saddr));
printf("dport: %d\n", s_event->dport); printf("dport: %d\n", s_event->dport);
printf("sport: %d\n\n", s_event->sport); printf("sport: %d\n", s_event->sport);
printf("qname: %s\n", s_event->qname);
printf("Class: ");
mapClass(s_event->class);
printf("Type: ");
mapType(s_event->type);
printf("\n");
return 0; return 0;
} }
int main(int argc, char *argv[]){ int main(int argc, char *argv[]){
@ -151,7 +233,8 @@ int main(int argc, char *argv[]){
} }
bpf_program__attach(programSkb); bpf_program__attach(programSkb);
int sock = open_raw_sock("wlp0s20f3"); //int sock = open_raw_sock("wlp0s20f3");
int sock = open_raw_sock("enx98e743c667fc");
printf("Socket: %d\n", sock); printf("Socket: %d\n", sock);
int prog_fd = bpf_program__fd(programSkb); int prog_fd = bpf_program__fd(programSkb);
printf("Program fd: %d\n", prog_fd); printf("Program fd: %d\n", prog_fd);

@ -31,67 +31,97 @@ struct {
/* /*
* https://datatracker.ietf.org/doc/html/rfc1035 * https://datatracker.ietf.org/doc/html/rfc1035
*/ */
static int dnsquery(struct __sk_buff *skb, struct ethhdr eth, struct iphdr ip, struct udphdr udp, int dport, int sport, int tlen){ static int dnsquery(struct __sk_buff *skb, struct ethhdr eth, struct iphdr ip, struct udphdr udp, int dport, int sport){
struct event s_event = {0}; struct event *s_event;
struct dnshdr dns = {0}; struct dnshdr dns = {0};
size_t dlen = 0; char saddr[32];
size_t qlen = 0; // Question len // bpf_printk("udp len: %d", ntohs(udp.len));
s_event.dport = dport;
s_event.sport = sport;
bpf_printk("port: %d %d", s_event.dport, s_event.sport);
//if (data + sizeof(struct ethhdr) + sizeof(struct iphdr) + sizeof(struct udphdr) + sizeof(struct dnshdr) > data_end)
// return 0;
//dns = (struct dnshdr *)(data + sizeof(struct ethhdr) + sizeof(struct iphdr) + sizeof(struct udphdr)); s_event = bpf_ringbuf_reserve(&m_data, sizeof(*s_event), 0);
//tlen += sizeof(struct dnshdr); if (!s_event)
bpf_printk("udp len: %d", ntohs(udp.len)); return 0;
/* Get IP header */
s_event->saddr = ip.saddr;
/* Get DNS header */
bpf_skb_load_bytes(skb, sizeof(struct ethhdr) + sizeof(struct iphdr) + sizeof(struct udphdr), &dns, sizeof(struct dnshdr)); bpf_skb_load_bytes(skb, sizeof(struct ethhdr) + sizeof(struct iphdr) + sizeof(struct udphdr), &dns, sizeof(struct dnshdr));
if (ntohs(dns.nbQuestions) == 0) if (ntohs(dns.nbQuestions) == 0){
bpf_ringbuf_discard(s_event, 0);
return 0; return 0;
}
bpf_printk("tid: %x", ntohs(dns.transactionID)); // Use as key map bpf_printk("tid: %x", ntohs(dns.transactionID)); // Use as key map
bpf_printk("nb question: %d", ntohs(dns.nbQuestions)); bpf_printk("nb question: %d", ntohs(dns.nbQuestions));
struct dns_query dquery; struct dns_query dquery;
bpf_skb_load_bytes(skb, sizeof(struct ethhdr) + sizeof(struct iphdr) + sizeof(struct udphdr) + sizeof(struct dnshdr), &dquery, sizeof(struct dns_query)); bpf_skb_load_bytes(skb, sizeof(struct ethhdr) + sizeof(struct iphdr) + sizeof(struct udphdr) + sizeof(struct dnshdr), &dquery, sizeof(struct dns_query));
bpf_printk("%s", dquery.name); //bpf_printk("%s", dquery.name);
bpf_printk("class: %d", ntohs(dquery.class)); //bpf_printk("class: %d", ntohs(dquery.class));
bpf_printk("type: %d", ntohs(dquery.type)); //bpf_printk("type: %d", ntohs(dquery.type));
// bpf_printk("size: %d %d %d", tlen, skb->len, (skb->len - tlen)); // bpf_printk("size: %d %d %d", tlen, skb->len, (skb->len - tlen));
dlen = (skb->len - tlen); //dlen = (skb->len - tlen);
bpf_printk("DNS packet len: %d", dlen); //bpf_printk("DNS packet len: %d", dlen);
qlen = dlen - sizeof(struct dnshdr); //qlen = dlen - sizeof(struct dnshdr);
bpf_printk("size: %d %d", sizeof(struct dnshdr), qlen); //bpf_printk("size: %d %d", sizeof(struct dnshdr), qlen);
char buf[128] = {0}; char buf[QNAME_SIZE] = {0};
bpf_skb_load_bytes(skb, sizeof(struct ethhdr) + sizeof(struct iphdr) + sizeof(struct udphdr) + sizeof(struct dnshdr), &buf, 41); bpf_skb_load_bytes(skb, sizeof(struct ethhdr) + sizeof(struct iphdr) + sizeof(struct udphdr) + sizeof(struct dnshdr), &buf, 41);
int index = 0; int index = 0;
char c = 0; int qname_len = 0; // Full length of the qname field
char t[15]; char *c = buf;
while (index != 15){ char qname[QNAME_SIZE] = {0};
c = buf[index];
if (c == '\0')
break; /*
t[index] = c; * The qname is composed by a the number of bytes then follow by the label
if (c == 0x3) * For instance, for the qname www.bucchino.org,
t[index] = '.'; * the first byte is the number of byte, here, it's 3, then we have www (in hex)
index++; * Then, we have the byte of 8 and follow by the label bucchino (size 8)
} * And to finish, we have 3 follow by org and we finish with the \0 character
bpf_printk("%s", t); * For instance, the result is:
// https://docs.cilium.io/en/stable/reference-guides/bpf/progtypes/ * 03 77 77 77 08 62 75 63 63 68 69 6e 6f 03 6f 72 67 00
if (bpf_ringbuf_output(&m_data, &s_event, sizeof(struct event), 0) == 0) */
return 0; while (*(c++) != '\0') {
//s_event = bpf_ringbuf_reserve(&m_data, sizeof(*s_event), 0); if(*c >= 'a' && *c <= 'z')
//if (!s_event) s_event->qname[index] = *c;
// return 0; else if(*c >= 'A' && *c <= 'Z')
//bpf_ringbuf_discard(s_event, 0); s_event->qname[index] = *c;
else
s_event->qname[index] = '.';
index++;
qname_len++;
}
s_event->qname[--index] = '\0';
qname_len++; // For the null character
bpf_printk("%s (%d) %d", s_event->qname, index, qname_len);
// Get class and type
uint16_t class, type;
bpf_skb_load_bytes(skb, sizeof(struct ethhdr) + sizeof(struct iphdr) + sizeof(struct udphdr) + sizeof(struct dnshdr) + qname_len, &type, sizeof(uint16_t));
bpf_skb_load_bytes(skb, sizeof(struct ethhdr) + sizeof(struct iphdr) + sizeof(struct udphdr) + sizeof(struct dnshdr) + qname_len + 2, &class, sizeof(uint16_t));
// https://docs.cilium.io/en/stable/reference-guides/bpf/progtypes/
s_event->dport = dport;
s_event->sport = sport;
s_event->class = ntohs(class);
s_event->type = ntohs(type);
//if(bpf_probe_read_user_str(&s_event->qname, sizeof(s_event->qname), qname) < 0)
// bpf_printk("Failed to copy qname");
// Add to map
bpf_ringbuf_submit(s_event, 0);
//bpf_ringbuf_submit(s_event, 0);
return 0; return 0;
} }
static int dnsanswer(struct __sk_buff *skb, struct ethhdr eth, struct iphdr ip, struct udphdr udp, int dport, int sport){
}
SEC("socket") SEC("socket")
int detect_dns(struct __sk_buff *skb) { int detect_dns(struct __sk_buff *skb) {
//void *data = (void *)(long)skb->data; //void *data = (void *)(long)skb->data;
@ -103,7 +133,6 @@ int detect_dns(struct __sk_buff *skb) {
unsigned long long h_proto, p; unsigned long long h_proto, p;
unsigned long long dport; unsigned long long dport;
unsigned long long sport; unsigned long long sport;
size_t tlen = 0;
//if (data + sizeof(struct ethhdr) + sizeof(struct iphdr) + sizeof(struct udphdr) > data_end) //if (data + sizeof(struct ethhdr) + sizeof(struct iphdr) + sizeof(struct udphdr) > data_end)
// return 0; // return 0;
@ -111,11 +140,9 @@ int detect_dns(struct __sk_buff *skb) {
//bpf_skb_load_bytes(skb, 12, &p, 2); //bpf_skb_load_bytes(skb, 12, &p, 2);
bpf_skb_load_bytes(skb, 0, &eth, sizeof(struct ethhdr)); bpf_skb_load_bytes(skb, 0, &eth, sizeof(struct ethhdr));
p = eth.h_proto; p = eth.h_proto;
tlen += sizeof(struct ethhdr);
if (ntohs(p) != ETH_P_IP) if (ntohs(p) != ETH_P_IP)
return 0; return 0;
tlen += sizeof(struct iphdr);
// bpf_printk("ip: %d",ntohs(p)); // bpf_printk("ip: %d",ntohs(p));
//ip = (struct iphdr*)(data + sizeof(struct ethhdr)); //ip = (struct iphdr*)(data + sizeof(struct ethhdr));
@ -127,8 +154,7 @@ int detect_dns(struct __sk_buff *skb) {
if (h_proto != 17) if (h_proto != 17)
return 0; return 0;
bpf_printk("proto: %d", h_proto); // bpf_printk("proto: %d", h_proto);
tlen += sizeof(struct udphdr);
//udp = (struct udphdr*)(data + sizeof(struct ethhdr) + sizeof(struct iphdr)); //udp = (struct udphdr*)(data + sizeof(struct ethhdr) + sizeof(struct iphdr));
bpf_skb_load_bytes(skb, sizeof(struct ethhdr) + sizeof(struct iphdr), &udp, sizeof(struct udphdr)); bpf_skb_load_bytes(skb, sizeof(struct ethhdr) + sizeof(struct iphdr), &udp, sizeof(struct udphdr));
@ -137,11 +163,8 @@ int detect_dns(struct __sk_buff *skb) {
dport = ntohs(udp.dest); dport = ntohs(udp.dest);
sport = ntohs(udp.source); sport = ntohs(udp.source);
//if (dport != 53)
// return 0;
if (dport == 53) if (dport == 53)
dnsquery(skb, eth, ip, udp, dport, sport, tlen); dnsquery(skb, eth, ip, udp, dport, sport);
else if(sport == 53) else if(sport == 53)
bpf_printk("Response"); bpf_printk("Response");

Binary file not shown.

193060
src/vmlinux.h

File diff suppressed because it is too large Load Diff