Update code
This commit is contained in:
parent
fa6681095c
commit
5812b581e8
BIN
dns-trace
BIN
dns-trace
Binary file not shown.
BIN
dns2.pcap
Normal file
BIN
dns2.pcap
Normal file
Binary file not shown.
BIN
dns3.pcap
Normal file
BIN
dns3.pcap
Normal file
Binary file not shown.
16
src/common.h
16
src/common.h
@ -1,6 +1,8 @@
|
|||||||
#ifndef H_COMMON
|
#ifndef H_COMMON
|
||||||
#define H_COMMON
|
#define H_COMMON
|
||||||
|
|
||||||
|
#define QNAME_SIZE 128
|
||||||
|
|
||||||
struct dnshdr {
|
struct dnshdr {
|
||||||
uint16_t transactionID;
|
uint16_t transactionID;
|
||||||
uint16_t flags;
|
uint16_t flags;
|
||||||
@ -11,17 +13,19 @@ struct dnshdr {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct dns_query {
|
struct dns_query {
|
||||||
char *name;
|
char *name;
|
||||||
//char name[112];
|
uint16_t type;
|
||||||
uint16_t type;
|
uint16_t class;
|
||||||
uint16_t class;
|
// struct dns_query *next;
|
||||||
struct dns_query *next;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct event {
|
struct event {
|
||||||
|
uint32_t saddr;
|
||||||
int dport;
|
int dport;
|
||||||
int sport;
|
int sport;
|
||||||
|
char qname[QNAME_SIZE];
|
||||||
|
int class;
|
||||||
|
int type;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -101,11 +101,93 @@ static int open_raw_sock(const char *name)
|
|||||||
return sock;
|
return sock;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void mapClass(const int class){
|
||||||
|
switch(class){
|
||||||
|
case 1:
|
||||||
|
printf("IN\n");
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
printf("CS\n");
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
printf("CH\n");
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
printf("HS\n");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
printf("Unknown\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
static void mapType(const int type){
|
||||||
|
switch(type){
|
||||||
|
case 1:
|
||||||
|
printf("A");
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
printf("NS");
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
printf("MD");
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
printf("MF");
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
printf("CNAME");
|
||||||
|
break;
|
||||||
|
case 6:
|
||||||
|
printf("SOA");
|
||||||
|
break;
|
||||||
|
case 7:
|
||||||
|
printf("MB");
|
||||||
|
break;
|
||||||
|
case 8:
|
||||||
|
printf("MG");
|
||||||
|
break;
|
||||||
|
case 9:
|
||||||
|
printf("MR");
|
||||||
|
break;
|
||||||
|
case 10:
|
||||||
|
printf("NULL");
|
||||||
|
break;
|
||||||
|
case 11:
|
||||||
|
printf("WKS");
|
||||||
|
break;
|
||||||
|
case 12:
|
||||||
|
printf("PTR");
|
||||||
|
break;
|
||||||
|
case 13:
|
||||||
|
printf("HINFO");
|
||||||
|
break;
|
||||||
|
case 14:
|
||||||
|
printf("MINFO");
|
||||||
|
break;
|
||||||
|
case 15:
|
||||||
|
printf("MX");
|
||||||
|
break;
|
||||||
|
case 16:
|
||||||
|
printf("TXT");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
printf("Unknown\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
|
||||||
int handle_event(void *ctx, void *data, size_t data_sz){
|
int handle_event(void *ctx, void *data, size_t data_sz){
|
||||||
struct event *s_event = (struct event*)data;
|
struct event *s_event = (struct event*)data;
|
||||||
|
printf("IP: %s\n", inet_ntoa(*(struct in_addr*)&s_event->saddr));
|
||||||
printf("dport: %d\n", s_event->dport);
|
printf("dport: %d\n", s_event->dport);
|
||||||
printf("sport: %d\n\n", s_event->sport);
|
printf("sport: %d\n", s_event->sport);
|
||||||
|
printf("qname: %s\n", s_event->qname);
|
||||||
|
printf("Class: ");
|
||||||
|
mapClass(s_event->class);
|
||||||
|
printf("Type: ");
|
||||||
|
mapType(s_event->type);
|
||||||
|
printf("\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
int main(int argc, char *argv[]){
|
int main(int argc, char *argv[]){
|
||||||
@ -151,7 +233,8 @@ int main(int argc, char *argv[]){
|
|||||||
}
|
}
|
||||||
|
|
||||||
bpf_program__attach(programSkb);
|
bpf_program__attach(programSkb);
|
||||||
int sock = open_raw_sock("wlp0s20f3");
|
//int sock = open_raw_sock("wlp0s20f3");
|
||||||
|
int sock = open_raw_sock("enx98e743c667fc");
|
||||||
printf("Socket: %d\n", sock);
|
printf("Socket: %d\n", sock);
|
||||||
int prog_fd = bpf_program__fd(programSkb);
|
int prog_fd = bpf_program__fd(programSkb);
|
||||||
printf("Program fd: %d\n", prog_fd);
|
printf("Program fd: %d\n", prog_fd);
|
||||||
|
@ -31,67 +31,97 @@ struct {
|
|||||||
/*
|
/*
|
||||||
* https://datatracker.ietf.org/doc/html/rfc1035
|
* 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, int tlen){
|
static int dnsquery(struct __sk_buff *skb, struct ethhdr eth, struct iphdr ip, struct udphdr udp, int dport, int sport){
|
||||||
struct event s_event = {0};
|
struct event *s_event;
|
||||||
struct dnshdr dns = {0};
|
struct dnshdr dns = {0};
|
||||||
size_t dlen = 0;
|
char saddr[32];
|
||||||
size_t qlen = 0; // Question len
|
// bpf_printk("udp len: %d", ntohs(udp.len));
|
||||||
s_event.dport = dport;
|
|
||||||
s_event.sport = sport;
|
|
||||||
bpf_printk("port: %d %d", s_event.dport, s_event.sport);
|
|
||||||
//if (data + sizeof(struct ethhdr) + sizeof(struct iphdr) + sizeof(struct udphdr) + sizeof(struct dnshdr) > data_end)
|
|
||||||
// return 0;
|
|
||||||
|
|
||||||
//dns = (struct dnshdr *)(data + sizeof(struct ethhdr) + sizeof(struct iphdr) + sizeof(struct udphdr));
|
s_event = bpf_ringbuf_reserve(&m_data, sizeof(*s_event), 0);
|
||||||
//tlen += sizeof(struct dnshdr);
|
if (!s_event)
|
||||||
bpf_printk("udp len: %d", ntohs(udp.len));
|
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));
|
bpf_skb_load_bytes(skb, sizeof(struct ethhdr) + sizeof(struct iphdr) + sizeof(struct udphdr), &dns, sizeof(struct dnshdr));
|
||||||
|
|
||||||
if (ntohs(dns.nbQuestions) == 0)
|
if (ntohs(dns.nbQuestions) == 0){
|
||||||
|
bpf_ringbuf_discard(s_event, 0);
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bpf_printk("tid: %x", ntohs(dns.transactionID)); // Use as key map
|
bpf_printk("tid: %x", ntohs(dns.transactionID)); // Use as key map
|
||||||
bpf_printk("nb question: %d", ntohs(dns.nbQuestions));
|
bpf_printk("nb question: %d", ntohs(dns.nbQuestions));
|
||||||
|
|
||||||
struct dns_query dquery;
|
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_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("%s", dquery.name);
|
||||||
bpf_printk("class: %d", ntohs(dquery.class));
|
//bpf_printk("class: %d", ntohs(dquery.class));
|
||||||
bpf_printk("type: %d", ntohs(dquery.type));
|
//bpf_printk("type: %d", ntohs(dquery.type));
|
||||||
// bpf_printk("size: %d %d %d", tlen, skb->len, (skb->len - tlen));
|
// bpf_printk("size: %d %d %d", tlen, skb->len, (skb->len - tlen));
|
||||||
dlen = (skb->len - tlen);
|
//dlen = (skb->len - tlen);
|
||||||
bpf_printk("DNS packet len: %d", dlen);
|
//bpf_printk("DNS packet len: %d", dlen);
|
||||||
qlen = dlen - sizeof(struct dnshdr);
|
//qlen = dlen - sizeof(struct dnshdr);
|
||||||
bpf_printk("size: %d %d", sizeof(struct dnshdr), qlen);
|
//bpf_printk("size: %d %d", sizeof(struct dnshdr), qlen);
|
||||||
char buf[128] = {0};
|
char buf[QNAME_SIZE] = {0};
|
||||||
|
|
||||||
|
|
||||||
bpf_skb_load_bytes(skb, sizeof(struct ethhdr) + sizeof(struct iphdr) + sizeof(struct udphdr) + sizeof(struct dnshdr), &buf, 41);
|
bpf_skb_load_bytes(skb, sizeof(struct ethhdr) + sizeof(struct iphdr) + sizeof(struct udphdr) + sizeof(struct dnshdr), &buf, 41);
|
||||||
int index = 0;
|
int index = 0;
|
||||||
char c = 0;
|
int qname_len = 0; // Full length of the qname field
|
||||||
char t[15];
|
char *c = buf;
|
||||||
while (index != 15){
|
char qname[QNAME_SIZE] = {0};
|
||||||
c = buf[index];
|
|
||||||
if (c == '\0')
|
|
||||||
break;
|
/*
|
||||||
t[index] = c;
|
* The qname is composed by a the number of bytes then follow by the label
|
||||||
if (c == 0x3)
|
* For instance, for the qname www.bucchino.org,
|
||||||
t[index] = '.';
|
* the first byte is the number of byte, here, it's 3, then we have www (in hex)
|
||||||
index++;
|
* Then, we have the byte of 8 and follow by the label bucchino (size 8)
|
||||||
}
|
* And to finish, we have 3 follow by org and we finish with the \0 character
|
||||||
bpf_printk("%s", t);
|
* For instance, the result is:
|
||||||
// https://docs.cilium.io/en/stable/reference-guides/bpf/progtypes/
|
* 03 77 77 77 08 62 75 63 63 68 69 6e 6f 03 6f 72 67 00
|
||||||
if (bpf_ringbuf_output(&m_data, &s_event, sizeof(struct event), 0) == 0)
|
*/
|
||||||
return 0;
|
while (*(c++) != '\0') {
|
||||||
//s_event = bpf_ringbuf_reserve(&m_data, sizeof(*s_event), 0);
|
if(*c >= 'a' && *c <= 'z')
|
||||||
//if (!s_event)
|
s_event->qname[index] = *c;
|
||||||
// return 0;
|
else if(*c >= 'A' && *c <= 'Z')
|
||||||
//bpf_ringbuf_discard(s_event, 0);
|
s_event->qname[index] = *c;
|
||||||
|
else
|
||||||
|
s_event->qname[index] = '.';
|
||||||
|
index++;
|
||||||
|
qname_len++;
|
||||||
|
}
|
||||||
|
s_event->qname[--index] = '\0';
|
||||||
|
qname_len++; // For the null character
|
||||||
|
bpf_printk("%s (%d) %d", s_event->qname, index, qname_len);
|
||||||
|
|
||||||
|
// Get class and type
|
||||||
|
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));
|
||||||
|
|
||||||
|
// https://docs.cilium.io/en/stable/reference-guides/bpf/progtypes/
|
||||||
|
s_event->dport = dport;
|
||||||
|
s_event->sport = sport;
|
||||||
|
s_event->class = ntohs(class);
|
||||||
|
s_event->type = ntohs(type);
|
||||||
|
//if(bpf_probe_read_user_str(&s_event->qname, sizeof(s_event->qname), qname) < 0)
|
||||||
|
// bpf_printk("Failed to copy qname");
|
||||||
|
|
||||||
|
// Add to map
|
||||||
|
|
||||||
|
bpf_ringbuf_submit(s_event, 0);
|
||||||
|
|
||||||
//bpf_ringbuf_submit(s_event, 0);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int dnsanswer(struct __sk_buff *skb, struct ethhdr eth, struct iphdr ip, struct udphdr udp, int dport, int sport){
|
||||||
|
|
||||||
|
}
|
||||||
SEC("socket")
|
SEC("socket")
|
||||||
int detect_dns(struct __sk_buff *skb) {
|
int detect_dns(struct __sk_buff *skb) {
|
||||||
//void *data = (void *)(long)skb->data;
|
//void *data = (void *)(long)skb->data;
|
||||||
@ -103,7 +133,6 @@ int detect_dns(struct __sk_buff *skb) {
|
|||||||
unsigned long long h_proto, p;
|
unsigned long long h_proto, p;
|
||||||
unsigned long long dport;
|
unsigned long long dport;
|
||||||
unsigned long long sport;
|
unsigned long long sport;
|
||||||
size_t tlen = 0;
|
|
||||||
|
|
||||||
//if (data + sizeof(struct ethhdr) + sizeof(struct iphdr) + sizeof(struct udphdr) > data_end)
|
//if (data + sizeof(struct ethhdr) + sizeof(struct iphdr) + sizeof(struct udphdr) > data_end)
|
||||||
// return 0;
|
// return 0;
|
||||||
@ -111,11 +140,9 @@ int detect_dns(struct __sk_buff *skb) {
|
|||||||
//bpf_skb_load_bytes(skb, 12, &p, 2);
|
//bpf_skb_load_bytes(skb, 12, &p, 2);
|
||||||
bpf_skb_load_bytes(skb, 0, ð, sizeof(struct ethhdr));
|
bpf_skb_load_bytes(skb, 0, ð, sizeof(struct ethhdr));
|
||||||
p = eth.h_proto;
|
p = eth.h_proto;
|
||||||
tlen += sizeof(struct ethhdr);
|
|
||||||
if (ntohs(p) != ETH_P_IP)
|
if (ntohs(p) != ETH_P_IP)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
tlen += sizeof(struct iphdr);
|
|
||||||
// bpf_printk("ip: %d",ntohs(p));
|
// bpf_printk("ip: %d",ntohs(p));
|
||||||
|
|
||||||
//ip = (struct iphdr*)(data + sizeof(struct ethhdr));
|
//ip = (struct iphdr*)(data + sizeof(struct ethhdr));
|
||||||
@ -127,8 +154,7 @@ int detect_dns(struct __sk_buff *skb) {
|
|||||||
if (h_proto != 17)
|
if (h_proto != 17)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
bpf_printk("proto: %d", h_proto);
|
// bpf_printk("proto: %d", h_proto);
|
||||||
tlen += sizeof(struct udphdr);
|
|
||||||
//udp = (struct udphdr*)(data + sizeof(struct ethhdr) + sizeof(struct iphdr));
|
//udp = (struct udphdr*)(data + sizeof(struct ethhdr) + sizeof(struct iphdr));
|
||||||
|
|
||||||
bpf_skb_load_bytes(skb, sizeof(struct ethhdr) + sizeof(struct iphdr), &udp, sizeof(struct udphdr));
|
bpf_skb_load_bytes(skb, sizeof(struct ethhdr) + sizeof(struct iphdr), &udp, sizeof(struct udphdr));
|
||||||
@ -137,11 +163,8 @@ int detect_dns(struct __sk_buff *skb) {
|
|||||||
dport = ntohs(udp.dest);
|
dport = ntohs(udp.dest);
|
||||||
sport = ntohs(udp.source);
|
sport = ntohs(udp.source);
|
||||||
|
|
||||||
//if (dport != 53)
|
|
||||||
// return 0;
|
|
||||||
|
|
||||||
if (dport == 53)
|
if (dport == 53)
|
||||||
dnsquery(skb, eth, ip, udp, dport, sport, tlen);
|
dnsquery(skb, eth, ip, udp, dport, sport);
|
||||||
else if(sport == 53)
|
else if(sport == 53)
|
||||||
bpf_printk("Response");
|
bpf_printk("Response");
|
||||||
|
|
||||||
|
Binary file not shown.
193060
src/vmlinux.h
193060
src/vmlinux.h
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user