diff --git a/src/common.h b/src/common.h index f80168d..58b056f 100644 --- a/src/common.h +++ b/src/common.h @@ -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; diff --git a/src/dns-trace.ebpf.c b/src/dns-trace.ebpf.c index 44beb2d..0d0ef93 100644 --- a/src/dns-trace.ebpf.c +++ b/src/dns-trace.ebpf.c @@ -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) { diff --git a/src/dns-trace.ebpf.o b/src/dns-trace.ebpf.o index 22ff216..5b9f491 100644 Binary files a/src/dns-trace.ebpf.o and b/src/dns-trace.ebpf.o differ