update code

This commit is contained in:
geoffrey 2025-02-01 16:58:29 +00:00
parent 1436099101
commit aa64b8f160
5 changed files with 131877 additions and 97 deletions

BIN
dns-trace

Binary file not shown.

@ -232,6 +232,19 @@ static void print_query(struct event *s_event){
free(type);
}
static void get_labels(unsigned char *buf, char *qname){
int pos = 0;
while (*buf++ != '\0') {
if((*buf >= 'a' && *buf <= 'z') || (*buf >= 'A' && *buf <= 'Z'))
*(qname + pos) = *buf;
else if (*buf >= '0' && *buf <= '9')
*(qname + pos) = *buf;
else
*(qname + pos) = '.';
pos++;
}
qname[pos - 1] = '\0';
}
int handle_event(void *ctx, void *data, size_t data_sz){
struct event *s_event = (struct event*)data;
if (s_event->req_type == REQ_QUERY){
@ -270,16 +283,23 @@ int handle_event(void *ctx, void *data, size_t data_sz){
}
if (type == 5) { // -> CNAME
char cname[size];
int j = 0;
for (j = 0; j < size; j++)
cname[j] = s_event->buf[pos + j];
get_labels(s_event->buf + pos, cname);
printf("%s ", cname);
}
if (type == 28){ // -> AAAA
int p = 0;
for (int i = 0; i < size; i++){
if (i % 2 == 0)
printf("%x", s_event->buf[pos + p++]);
else{
if (i<size - 1)
printf("%x:", s_event->buf[pos + p++]);
else
printf("%x", s_event->buf[pos + p++]);
}
}
}
pos += size;
//printf("\n %d ", pos);
printf("\n");
}
}

@ -29,24 +29,28 @@ struct {
__uint(max_entries, 256 * 1024 /* 256kb */);
} m_data SEC(".maps");
struct {
__uint(type, BPF_MAP_TYPE_HASH);
__uint(max_entries, 32768);
__type(key, uint16_t);
__type(value, struct dns_answer);
} m_tid SEC(".maps");
static size_t get_labels2(struct __sk_buff *skb, size_t offset, struct event *s_event){
static size_t get_labels(struct __sk_buff *skb, size_t offset, struct event *s_event){
char c;
int qname_len = 0;
//bpf_printk("labels off: %d", offset);
bpf_skb_load_bytes(skb, offset, &c, 1); // Get the first byte, which is the length
int pos = 1;
/*
* 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') {
bpf_skb_load_bytes(skb, offset + pos++, &c, 1);
if(c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z')
s_event->qname[qname_len] = c;
else if(c >= '0' && c <= '9')
s_event->qname[qname_len] = c;
else
s_event->qname[qname_len] = '.';
qname_len++;
@ -60,41 +64,6 @@ static size_t get_labels2(struct __sk_buff *skb, size_t offset, struct event *s_
// bpf_printk("qname len: %d", qname_len);
return qname_len;
}
static size_t get_labels(struct __sk_buff *skb, size_t offset, size_t end, struct event *s_event, struct query_section *s_query){
//size_t len;
char buf[256] = {0};
char *c;
int index = 0;
size_t qname_len = 0; // Full length of the qname field
bpf_skb_load_bytes(skb, offset, &buf, 41);
c = buf;
/*
* 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("qname: %s", s_event->qname);
return qname_len;
}
/*
* This function get the query field and the return the length of it
@ -105,7 +74,7 @@ static size_t get_query_section(struct __sk_buff *skb, struct event *s_event, ui
uint16_t class, type;
offset += sizeof(struct dnshdr);
qname_len = get_labels2(skb, offset, s_event);
qname_len = get_labels(skb, offset, s_event);
// Get class and type
len = qname_len;
@ -185,7 +154,7 @@ static unsigned int get_answer(struct __sk_buff *skb, struct event *s_event, siz
tlen += ntohs(size);
}
else {
// get_labels2(skb, sizeof(struct ethhdr) + sizeof(struct iphdr) + sizeof(struct udphdr) + sizeof(struct dnshdr), s_event);
// get_labels(skb, sizeof(struct ethhdr) + sizeof(struct iphdr) + sizeof(struct udphdr) + sizeof(struct dnshdr), s_event);
}
bpf_printk("End offset: %d", offset);
return offset;
@ -275,11 +244,6 @@ static void dnsanswer_old(struct __sk_buff *skb, struct iphdr ip, struct udphdr
}
/*
TODO: je recupere tout le skb->data, grace au skb->len
grace a ca, j'aurai tout le payload udp et toute les donnees dns
je pourrai facilement parcourir les data
*/
static void dnsanswer(struct __sk_buff *skb, struct iphdr ip, struct udphdr udp, int dport, int sport){
struct event *s_event;
struct dnshdr dns;
@ -356,12 +320,8 @@ static void dnsanswer(struct __sk_buff *skb, struct iphdr ip, struct udphdr udp,
/*
* skb -> http://oldvger.kernel.org/~davem/skb_data.html
*/
SEC("socket")
int detect_dns(struct __sk_buff *skb) {
//void *data = (void *)(long)skb->data;
//void *data_end = (void *)(long)skb->data_end;
//struct ethhdr *eth2 = data;
struct ethhdr eth = {0};
struct iphdr ip = {0};
struct udphdr udp = {0};
@ -369,32 +329,22 @@ int detect_dns(struct __sk_buff *skb) {
__u32 dport;
__u32 sport;
//if (data + sizeof(struct ethhdr) + sizeof(struct iphdr) + sizeof(struct udphdr) > data_end)
// return 0;
if (skb->len < sizeof(struct ethhdr) + sizeof(struct iphdr) + sizeof(struct udphdr))
return 0;
//bpf_skb_load_bytes(skb, 12, &p, 2);
bpf_skb_load_bytes(skb, 0, &eth, sizeof(struct ethhdr));
p = eth.h_proto;
if (ntohs(p) != ETH_P_IP)
return 0;
// bpf_printk("ip: %d",ntohs(p));
//ip = (struct iphdr*)(data + sizeof(struct ethhdr));
bpf_skb_load_bytes(skb, sizeof(struct ethhdr), &ip, sizeof(struct iphdr));
//bpf_skb_load_bytes(data, sizeof(struct ethhdr), ip, sizeof(struct ip));
h_proto = ip.protocol;
// If not UDP packet
if (h_proto != 17)
return 0;
// 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));
if (udp.len == 0)
@ -411,31 +361,4 @@ int detect_dns(struct __sk_buff *skb) {
return 0;
}
/*SEC("xdp")
int detect_dns(struct xdp_md *ctx){
void *data_end = (void *)(long)ctx->data_end;
void *data = (void *)(long)ctx->data;
struct ethhdr *eth = data;
struct iphdr *ip;
struct udphdr *udp;
__u16 h_proto;
__u16 dport;
if (data + sizeof(struct ethhdr) + sizeof(struct iphdr) + sizeof(struct udphdr) > data_end)
return XDP_DROP;
ip = (struct iphdr*)(data + sizeof(struct ethhdr));
udp = (struct udphdr*)(data + sizeof(struct ethhdr) + sizeof(struct iphdr));
h_proto = ip->protocol;
// If not UDP packet
if (h_proto != 17)
return XDP_PASS;
// Check if DNS port
dport = udp->dest;
bpf_printk("Dport: %d", (dport));
return XDP_PASS;
}*/
char LICENSE[] SEC("license") = "GPL";

Binary file not shown.

131837
src/vmlinux.h

File diff suppressed because it is too large Load Diff