This commit is contained in:
geoffrey 2025-01-30 18:55:58 +00:00
parent 8210e56090
commit c775f97f3c
4 changed files with 32 additions and 41 deletions

BIN
dns-trace

Binary file not shown.

@ -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");

@ -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");
}
/*

Binary file not shown.