Update code
This commit is contained in:
+7
-3
@@ -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;
|
||||||
@@ -12,16 +14,18 @@ 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
|
||||||
|
|||||||
+85
-2
@@ -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);
|
||||||
|
|||||||
+70
-47
@@ -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)
|
||||||
|
* 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++;
|
index++;
|
||||||
|
qname_len++;
|
||||||
}
|
}
|
||||||
bpf_printk("%s", t);
|
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/
|
// https://docs.cilium.io/en/stable/reference-guides/bpf/progtypes/
|
||||||
if (bpf_ringbuf_output(&m_data, &s_event, sizeof(struct event), 0) == 0)
|
s_event->dport = dport;
|
||||||
return 0;
|
s_event->sport = sport;
|
||||||
//s_event = bpf_ringbuf_reserve(&m_data, sizeof(*s_event), 0);
|
s_event->class = ntohs(class);
|
||||||
//if (!s_event)
|
s_event->type = ntohs(type);
|
||||||
// return 0;
|
//if(bpf_probe_read_user_str(&s_event->qname, sizeof(s_event->qname), qname) < 0)
|
||||||
//bpf_ringbuf_discard(s_event, 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.
+123014
-69796
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user