Get answer
This commit is contained in:
parent
1051b50931
commit
2cb21c1f55
@ -25,6 +25,14 @@ struct event {
|
||||
char qname[QNAME_SIZE];
|
||||
int class;
|
||||
int type;
|
||||
char ans[32];
|
||||
};
|
||||
|
||||
struct dns_answer {
|
||||
uint16_t tid;
|
||||
char qname[QNAME_SIZE];
|
||||
char ip[32];
|
||||
int ttl;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -28,6 +28,14 @@ struct {
|
||||
__uint(max_entries, 256 * 1024 /* 256kb */);
|
||||
} m_data SEC(".maps");
|
||||
|
||||
struct {
|
||||
__uint(type, BPF_MAP_TYPE_HASH);
|
||||
__uint(max_entries, 32768); // pid_max -> https://linux.die.net/man/5/proc
|
||||
__type(key, uint16_t);
|
||||
__type(value, struct dns_answer);
|
||||
} m_tid SEC(".maps");
|
||||
|
||||
|
||||
/*
|
||||
* This function get the query field and the return the length of it
|
||||
*/
|
||||
@ -84,6 +92,7 @@ static int dnsquery(struct __sk_buff *skb, struct ethhdr eth, struct iphdr ip, s
|
||||
struct dnshdr dns = {0};
|
||||
char saddr[32];
|
||||
uint16_t class, type;
|
||||
//struct dns_answer s_dnsanswer;
|
||||
// bpf_printk("udp len: %d", ntohs(udp.len));
|
||||
|
||||
s_event = bpf_ringbuf_reserve(&m_data, sizeof(*s_event), 0);
|
||||
@ -101,7 +110,6 @@ static int dnsquery(struct __sk_buff *skb, struct ethhdr eth, struct iphdr ip, s
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
bpf_printk("tid: %x", ntohs(dns.transactionID)); // Use as key map
|
||||
bpf_printk("nb question: %d", ntohs(dns.nbQuestions));
|
||||
|
||||
@ -134,6 +142,49 @@ 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){
|
||||
struct event *s_event;
|
||||
struct dnshdr dns = {0};
|
||||
uint16_t tid = 0;
|
||||
struct dns_answer s_dnsanswer;
|
||||
|
||||
/* Get DNS header */
|
||||
bpf_skb_load_bytes(skb, sizeof(struct ethhdr) + sizeof(struct iphdr) + sizeof(struct udphdr), &dns, sizeof(struct dnshdr));
|
||||
|
||||
s_event = bpf_ringbuf_reserve(&m_data, sizeof(*s_event), 0);
|
||||
if (!s_event)
|
||||
return 0;
|
||||
|
||||
/* Get the Transaction ID */
|
||||
tid = ntohs(dns.transactionID);
|
||||
bpf_printk("tid: %x", tid);
|
||||
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
/*
|
||||
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 query response */
|
||||
size_t tlen = sizeof(struct ethhdr) + sizeof(struct iphdr) + sizeof(struct udphdr) + sizeof(struct dnshdr);
|
||||
uint16_t class, type;
|
||||
size_t query_len = get_query(skb, s_event, &class, &type, tlen);
|
||||
bpf_printk("answer qname: %s", s_event->qname);
|
||||
|
||||
/* Get the answer */
|
||||
|
||||
bpf_ringbuf_submit(s_event, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
SEC("socket")
|
||||
@ -180,7 +231,7 @@ int detect_dns(struct __sk_buff *skb) {
|
||||
if (dport == 53)
|
||||
dnsquery(skb, eth, ip, udp, dport, sport);
|
||||
else if(sport == 53)
|
||||
bpf_printk("Response");
|
||||
dnsanswer(skb, eth, ip, udp, dport, sport);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
Binary file not shown.
Loading…
Reference in New Issue
Block a user