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
|
||||
#define H_COMMON
|
||||
|
||||
#define QNAME_SIZE 128
|
||||
|
||||
struct dnshdr {
|
||||
uint16_t transactionID;
|
||||
uint16_t flags;
|
||||
@ -11,17 +13,19 @@ struct dnshdr {
|
||||
};
|
||||
|
||||
struct dns_query {
|
||||
char *name;
|
||||
//char name[112];
|
||||
uint16_t type;
|
||||
uint16_t class;
|
||||
struct dns_query *next;
|
||||
char *name;
|
||||
uint16_t type;
|
||||
uint16_t class;
|
||||
// struct dns_query *next;
|
||||
};
|
||||
|
||||
struct event {
|
||||
uint32_t saddr;
|
||||
int dport;
|
||||
int sport;
|
||||
|
||||
char qname[QNAME_SIZE];
|
||||
int class;
|
||||
int type;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -101,11 +101,93 @@ static int open_raw_sock(const char *name)
|
||||
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){
|
||||
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("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;
|
||||
}
|
||||
int main(int argc, char *argv[]){
|
||||
@ -151,7 +233,8 @@ int main(int argc, char *argv[]){
|
||||
}
|
||||
|
||||
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);
|
||||
int prog_fd = bpf_program__fd(programSkb);
|
||||
printf("Program fd: %d\n", prog_fd);
|
||||
|
@ -31,67 +31,97 @@ struct {
|
||||
/*
|
||||
* 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){
|
||||
struct event s_event = {0};
|
||||
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};
|
||||
size_t dlen = 0;
|
||||
size_t qlen = 0; // Question 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;
|
||||
char saddr[32];
|
||||
// bpf_printk("udp len: %d", ntohs(udp.len));
|
||||
|
||||
//dns = (struct dnshdr *)(data + sizeof(struct ethhdr) + sizeof(struct iphdr) + sizeof(struct udphdr));
|
||||
//tlen += sizeof(struct dnshdr);
|
||||
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)
|
||||
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("%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);
|
||||
char buf[128] = {0};
|
||||
//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);
|
||||
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;
|
||||
char c = 0;
|
||||
char t[15];
|
||||
while (index != 15){
|
||||
c = buf[index];
|
||||
if (c == '\0')
|
||||
break;
|
||||
t[index] = c;
|
||||
if (c == 0x3)
|
||||
t[index] = '.';
|
||||
index++;
|
||||
}
|
||||
bpf_printk("%s", t);
|
||||
// https://docs.cilium.io/en/stable/reference-guides/bpf/progtypes/
|
||||
if (bpf_ringbuf_output(&m_data, &s_event, sizeof(struct event), 0) == 0)
|
||||
return 0;
|
||||
//s_event = bpf_ringbuf_reserve(&m_data, sizeof(*s_event), 0);
|
||||
//if (!s_event)
|
||||
// return 0;
|
||||
//bpf_ringbuf_discard(s_event, 0);
|
||||
int qname_len = 0; // Full length of the qname field
|
||||
char *c = buf;
|
||||
char qname[QNAME_SIZE] = {0};
|
||||
|
||||
|
||||
/*
|
||||
* The qname is composed by a the number of bytes then follow by the label
|
||||
* For instance, for the qname www.bucchino.org,
|
||||
* the first byte is the number of byte, here, it's 3, then we have www (in hex)
|
||||
* 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
|
||||
* For instance, the result is:
|
||||
* 03 77 77 77 08 62 75 63 63 68 69 6e 6f 03 6f 72 67 00
|
||||
*/
|
||||
while (*(c++) != '\0') {
|
||||
if(*c >= 'a' && *c <= 'z')
|
||||
s_event->qname[index] = *c;
|
||||
else if(*c >= 'A' && *c <= 'Z')
|
||||
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;
|
||||
}
|
||||
|
||||
static int dnsanswer(struct __sk_buff *skb, struct ethhdr eth, struct iphdr ip, struct udphdr udp, int dport, int sport){
|
||||
|
||||
}
|
||||
SEC("socket")
|
||||
int detect_dns(struct __sk_buff *skb) {
|
||||
//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 dport;
|
||||
unsigned long long sport;
|
||||
size_t tlen = 0;
|
||||
|
||||
//if (data + sizeof(struct ethhdr) + sizeof(struct iphdr) + sizeof(struct udphdr) > data_end)
|
||||
// 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, 0, ð, sizeof(struct ethhdr));
|
||||
p = eth.h_proto;
|
||||
tlen += sizeof(struct ethhdr);
|
||||
if (ntohs(p) != ETH_P_IP)
|
||||
return 0;
|
||||
|
||||
tlen += sizeof(struct iphdr);
|
||||
// bpf_printk("ip: %d",ntohs(p));
|
||||
|
||||
//ip = (struct iphdr*)(data + sizeof(struct ethhdr));
|
||||
@ -127,8 +154,7 @@ int detect_dns(struct __sk_buff *skb) {
|
||||
if (h_proto != 17)
|
||||
return 0;
|
||||
|
||||
bpf_printk("proto: %d", h_proto);
|
||||
tlen += sizeof(struct udphdr);
|
||||
// bpf_printk("proto: %d", h_proto);
|
||||
//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));
|
||||
@ -137,11 +163,8 @@ int detect_dns(struct __sk_buff *skb) {
|
||||
dport = ntohs(udp.dest);
|
||||
sport = ntohs(udp.source);
|
||||
|
||||
//if (dport != 53)
|
||||
// return 0;
|
||||
|
||||
if (dport == 53)
|
||||
dnsquery(skb, eth, ip, udp, dport, sport, tlen);
|
||||
dnsquery(skb, eth, ip, udp, dport, sport);
|
||||
else if(sport == 53)
|
||||
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