Get query from function

This commit is contained in:
gbucchino 2025-01-15 14:12:46 +01:00
parent 5812b581e8
commit 1051b50931
3 changed files with 59 additions and 46 deletions

@ -12,12 +12,11 @@ struct dnshdr {
uint16_t nbAdditionalRRs;
};
struct dns_query {
/*struct dns_query {
char *name;
uint16_t type;
uint16_t class;
// struct dns_query *next;
};
};*/
struct event {
uint32_t saddr;

@ -29,52 +29,19 @@ struct {
} m_data SEC(".maps");
/*
* https://datatracker.ietf.org/doc/html/rfc1035
* This function get the query field and the return the length of it
*/
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};
char saddr[32];
// bpf_printk("udp len: %d", ntohs(udp.len));
s_event = bpf_ringbuf_reserve(&m_data, sizeof(*s_event), 0);
if (!s_event)
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));
if (ntohs(dns.nbQuestions) == 0){
bpf_ringbuf_discard(s_event, 0);
return 0;
}
bpf_printk("tid: %x", ntohs(dns.transactionID)); // Use as key map
bpf_printk("nb question: %d", ntohs(dns.nbQuestions));
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_printk("%s", dquery.name);
//bpf_printk("class: %d", ntohs(dquery.class));
//bpf_printk("type: %d", ntohs(dquery.type));
// bpf_printk("size: %d %d %d", tlen, skb->len, (skb->len - tlen));
//dlen = (skb->len - tlen);
//bpf_printk("DNS packet len: %d", dlen);
//qlen = dlen - sizeof(struct dnshdr);
//bpf_printk("size: %d %d", sizeof(struct dnshdr), qlen);
static size_t get_query(struct __sk_buff *skb, struct event *s_event, uint16_t *class, uint16_t *type, size_t tlen){
size_t len;
char buf[QNAME_SIZE] = {0};
bpf_skb_load_bytes(skb, sizeof(struct ethhdr) + sizeof(struct iphdr) + sizeof(struct udphdr) + sizeof(struct dnshdr), &buf, 41);
int index = 0;
int qname_len = 0; // Full length of the qname field
char *c = buf;
char qname[QNAME_SIZE] = {0};
char *c;
bpf_skb_load_bytes(skb, tlen, &buf, 41);
c = buf;
/*
* The qname is composed by a the number of bytes then follow by the label
@ -100,9 +67,56 @@ static int dnsquery(struct __sk_buff *skb, struct ethhdr eth, struct iphdr ip, s
bpf_printk("%s (%d) %d", s_event->qname, index, qname_len);
// Get class and type
len = qname_len;
bpf_skb_load_bytes(skb, tlen + qname_len, type, sizeof(uint16_t));
len += 2;
bpf_skb_load_bytes(skb, tlen + qname_len + 2, class, sizeof(uint16_t));
len += 2;
return len;
}
/*
* 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){
struct event *s_event;
struct dnshdr dns = {0};
char saddr[32];
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));
// bpf_printk("udp len: %d", ntohs(udp.len));
s_event = bpf_ringbuf_reserve(&m_data, sizeof(*s_event), 0);
if (!s_event)
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));
if (ntohs(dns.nbQuestions) == 0){
bpf_ringbuf_discard(s_event, 0);
return 0;
}
bpf_printk("tid: %x", ntohs(dns.transactionID)); // Use as key map
bpf_printk("nb question: %d", ntohs(dns.nbQuestions));
//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_printk("size: %d %d %d", tlen, skb->len, (skb->len - tlen));
//dlen = (skb->len - tlen);
//bpf_printk("DNS packet len: %d", dlen);
//qlen = dlen - sizeof(struct dnshdr);
//bpf_printk("size: %d %d", sizeof(struct dnshdr), qlen);
/* Get the query structure */
size_t tlen = sizeof(struct ethhdr) + sizeof(struct iphdr) + sizeof(struct udphdr) + sizeof(struct dnshdr);
size_t query_len = get_query(skb, s_event, &class, &type, tlen);
// https://docs.cilium.io/en/stable/reference-guides/bpf/progtypes/
s_event->dport = dport;
@ -120,7 +134,7 @@ static int dnsquery(struct __sk_buff *skb, struct ethhdr eth, struct iphdr ip, s
}
static int dnsanswer(struct __sk_buff *skb, struct ethhdr eth, struct iphdr ip, struct udphdr udp, int dport, int sport){
return 0;
}
SEC("socket")
int detect_dns(struct __sk_buff *skb) {

Binary file not shown.