diff --git a/dns-trace b/dns-trace index 94d36e2..be1b66a 100755 Binary files a/dns-trace and b/dns-trace differ diff --git a/src/dns-trace.c b/src/dns-trace.c index 53199c3..24837a1 100644 --- a/src/dns-trace.c +++ b/src/dns-trace.c @@ -239,11 +239,14 @@ int handle_event(void *ctx, void *data, size_t data_sz){ } if (s_event->req_type == REQ_ANSWER){ int pos = 0; - //for(int i = 0; i < 32; i++) - // printf("%d ", s_event->buf[i]); - //printf("\n"); + for (int i = 0; i < 32; i++) + printf("%d ", s_event->buf[i]); + printf("\n"); for (int i = 0; i < s_event->numAns; i++){ print_query(s_event); + } + /*for (int i = 0; i < s_event->numAns; i++){ + print_query(s_event); uint16_t type2 = (s_event->buf[pos++]) + (s_event->buf[pos++] << 8); uint16_t class2 = (s_event->buf[pos++]) + (s_event->buf[pos++] << 8); uint32_t ttl2 = (s_event->buf[pos++]) + (s_event->buf[pos++] << 8) + (s_event->buf[pos++] << 16) + (s_event->buf[pos++] << 24); @@ -261,7 +264,7 @@ int handle_event(void *ctx, void *data, size_t data_sz){ } printf("\n"); printf("%d\n", pos); - } + }*/ } printf("\n"); diff --git a/src/dns-trace.ebpf.c b/src/dns-trace.ebpf.c index 55821cc..1f668c3 100644 --- a/src/dns-trace.ebpf.c +++ b/src/dns-trace.ebpf.c @@ -285,9 +285,16 @@ static void dnsanswer(struct __sk_buff *skb, struct iphdr ip, struct udphdr udp, 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; + + if (tlen < 0 || tlen >= 256) + return; + + bpf_printk("udp len: %d", tlen); // Load dns header - if (bpf_skb_load_bytes(skb, offset, &dns, 12) < 0) + if (bpf_skb_load_bytes(skb, offset, &dns, sizeof(struct dnshdr)) < 0) return; // Check OpCode @@ -312,7 +319,7 @@ static void dnsanswer(struct __sk_buff *skb, struct iphdr ip, struct udphdr udp, /* Get the Transaction ID */ s_event->tid = ntohs(dns.transactionID); - + /* Get the query section */ size_t query_len = get_query_section(skb, s_event, offset); @@ -323,46 +330,27 @@ static void dnsanswer(struct __sk_buff *skb, struct iphdr ip, struct udphdr udp, return; } - if (ans > 0){ - /* - * We get a least the 5 last answer - * In the RFC 1035 (https://datatracker.ietf.org/doc/html/rfc1035#section-2.3.4) the max udp payload is 512 bytes - * The program limit size of the answer - */ - offset += sizeof(struct dnshdr) + query_len; // For the pos in the answer section in the skb - unsigned int offset_ans = 0; - for (uint16_t i = 0; i < ans; i++){ - offset_ans += get_answer(skb, s_event, offset, offset_ans); - offset += offset_ans + 2; // +2 for the message compression - //offset_ans += offset_ans; - // For eBPF verifier, to be sure we leave the loop - if (i == ans || i == 5 || offset_ans >= 512) - break; - } + /*if (ans > 0){ s_event->numAns = ans; - } - if (ntohs(dns.nbAuthorityRRs) > 0){ + }*/ + s_event->numAns = ans; - } + + // Load query and answer /* - * In the user space, if the haven't have the answer, we can have an error - * The solution is to push to the ring buffer and the answer is store in - * the struct event - * Or, we push to the ring buffer and the query only with the map - * but, if we haven't have the answer, we need print the query + * 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 */ - - /* - Pour recuperer les infos: - 1 - dans le getquery, on push dans le ringbuffer et dans le userspace, on recupere aussi la reponse - mais si la reponse, nous l'avons pas encore, ca fail et dans le get answer on push dans une map - 2 - on push dans le ring buffer quand on a la reponse avec la requette car c'est dans le field query - cependant, si on a pas la reponse, on n'aura jamais la query - 3 - dans le get query et get answer, on push dans le ring buffer et tout est store dans le struct event - */ - - /* Get the answer */ + 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++; + } bpf_ringbuf_submit(s_event, 0); + //if(bpf_skb_load_bytes(skb, offset, &buf, tlen) < 0) + // bpf_printk("Failed"); } /* diff --git a/src/dns-trace.ebpf.o b/src/dns-trace.ebpf.o index e86850e..b3c86a7 100644 Binary files a/src/dns-trace.ebpf.o and b/src/dns-trace.ebpf.o differ