Skip to content

Commit

Permalink
DNS Initial Support
Browse files Browse the repository at this point in the history
  • Loading branch information
wtfbbqhax committed Sep 3, 2024
1 parent 54cb7d2 commit 5cbca2f
Show file tree
Hide file tree
Showing 11 changed files with 90 additions and 63 deletions.
2 changes: 1 addition & 1 deletion Containerfile
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Using www.github.com/wtfbbqhax/krakatoa
FROM arm64v8/krakatoa AS libpacket_dev_env
FROM amd64/krakatoa AS libpacket_dev_env

USER root
RUN apk update
Expand Down
File renamed without changes.
2 changes: 1 addition & 1 deletion piglet-bpf-filter/Makefile → bin/Makefile
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#!/usr/bin/env bash

piglet-bpf-filter: piglet-bpf-filter.cc daq_print.cc daq_print.h
dns-hog: dns_hog.cc daq_print.cc daq_print.h
c++ -ggdb -std=c++14 -lstdc++ $^ -lpcap -ldaq -lpacket -o $@

clean:
Expand Down
35 changes: 18 additions & 17 deletions piglet-bpf-filter/daq_print.cc → bin/daq_print.cc
Original file line number Diff line number Diff line change
Expand Up @@ -36,22 +36,22 @@ int print_dns(dns const& dns)
{
bool is_response = DNS_QR(dns.h.flags);

if (is_response)
//if (is_response)
{
printf("[dns response] [rcode:%d, id:%d, qdcount: %d, ancount: %d, nscount: %d, arcount:%d]\n",
printf("[dns] [rcode:%d, id:%d, qdcount: %d, ancount: %d, nscount: %d, arcount:%d]\n",
DNS_RCODE(dns.h.flags),
dns.h.id,
dns.h.qdcount,
dns.h.ancount,
dns.h.nscount,
dns.h.arcount);
}
else
{
printf("[dns query] [id:%d, qdcount: %d]\n",
dns.h.id,
dns.h.qdcount);
}
//else
//{
// printf("[dns query] [id:%d, qdcount: %d]\n",
// dns.h.id,
// dns.h.qdcount);
//}

// Parsing Question Section
for (int i = 0; i < dns.h.qdcount; i++)
Expand All @@ -78,7 +78,11 @@ int print_dns(dns const& dns)
{
inet_ntop(AF_INET, a.data.data(), addr, sizeof(addr));
human.append(addr, strnlen(addr, INET6_ADDRSTRLEN));

}
else if (a.dns_atype == 28)
{
inet_ntop(AF_INET6, a.data.data(), addr, sizeof(addr));
human.append(addr, strnlen(addr, INET6_ADDRSTRLEN));
}
else
{
Expand All @@ -95,6 +99,7 @@ int print_dns(dns const& dns)
// (void)dns[0].questions[i].dns_qclass;
}

printf("\n");
return 0;
}

Expand Down Expand Up @@ -179,21 +184,17 @@ print_packet(int const instance_id, DAQ_PktHdr_t const* hdr, uint8_t const * dat
packet_frag_mf(&packet) ? "mf" : "");
}

uint32_t max = packet_paysize(&packet);
const uint8_t *payload = packet_payload(&packet);
if (sport == 53 || dport == 53)
{
dns _dns;
decode_dns(packet_payload(&packet),
packet_paysize(&packet),
&_dns);
decode_dns(payload, max, &_dns);
print_dns(_dns);
}

uint32_t max = packet_paysize(&packet);
const uint8_t *payload = packet_payload(&packet);
max = max > 128 ? 128 : max;
print_data(payload, max);

//print_data(data, len);
//print_data(payload, max);

#ifdef PRINT_PACKET_STATS
// Packet stats are useful for determining decoding errors
Expand Down
File renamed without changes.
Binary file added bin/dns-hog
Binary file not shown.
16 changes: 7 additions & 9 deletions piglet-bpf-filter/piglet-bpf-filter.cc → bin/dns_hog.cc
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,7 @@
#include <packet/dns.h>
#include <pcap.h>

//#include <sfbpf.h>
//#include <sfbpf_dlt.h>

#define TXT_FG_PURPLE(str) "\e[35m" str "\e[0m"

#include "daq_print.h"

Expand Down Expand Up @@ -441,7 +439,8 @@ class DataPlaneWorker
}

verdicts.verdicts[i] = verdict;
printf(matched ? "[match|%s] " : "[%s]", str_from_verdict(verdict));
printf(matched ? "[" TXT_FG_PURPLE("match") "] " : "");
printf("[%s] ", str_from_verdict(verdict));
print_packet(id, hdr, data, hdr->pktlen);
}
}
Expand Down Expand Up @@ -508,9 +507,9 @@ int main(int argc, char const* argv[])
//{ "debug", "true" },
};

if (argc < 3)
if (argc < 2)
{
fprintf(stderr, "Usage: piglet-bpf-filter [pass|block|allowlist|blocklist] <BPF expression>\n");
fprintf(stderr, "Usage: piglet-bpf-filter <BPF expression>\n");
exit(1);
}

Expand All @@ -520,13 +519,12 @@ int main(int argc, char const* argv[])

DaqConfig pcap_config("pcap", "pcaps/dns.pcap", DAQ_MODE_READ_FILE, vars);
DataPlaneWorker wk0(pcap_config, 0, filter, match_verdict, default_verdict);

sleep(2);

wk0.stop();
wk0.join();

//DataPlaneWorker wk1(vpp_inline_config, 1, filter, match_verdict, default_verdict);
//wk1.stop(); wk1.join();

DAQ::unload_modules();
return 0;
}
Binary file added bin/pcaps/dns-label-loop.pcap
Binary file not shown.
File renamed without changes.
2 changes: 1 addition & 1 deletion include/packet/dns.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,6 @@ enum dns_types {
TYPE_TXT // 16
};

int decode_dns(uint8_t const *pkt, uint32_t const len, dns* dns);
extern "C" int decode_dns(uint8_t const *pkt, uint32_t const len, dns* dns);

#endif /* LIBPACKET_DECODE_DNS_H */
96 changes: 62 additions & 34 deletions src/dns.cc
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,43 @@
#include "packet_private.h"
#include "packet/dns.h"

#define IS_SET(test, bits) (((test) & (bits)) == (bits))

struct dns_stats s_dns_stats;

uint32_t constexpr MINIMUM_DNS_HEADER_SIZE = (sizeof(dns_header));

//static inline void
extern "C" void
decode_label(uint8_t const* raw, uint8_t const* ptr, std::string& _label)
{
uint8_t off;
uint8_t label_len;

if (ptr[0] == 0) {
return;
}

scan_again:
if (IS_SET(ptr[0], 0xC0)) {
off = ptr[1];
ptr = &raw[off];
}

label_len = ptr[0];
ptr++;

_label.append(reinterpret_cast<char const*>(ptr), label_len);
_label.append(".");
ptr += label_len;

if (ptr[0] != 0) {
goto scan_again;
}
}

// Function to decode the DNS protocol
int
extern "C" int
decode_dns(uint8_t const * pkt, uint32_t const len, dns* dns)
{
if (len < MINIMUM_DNS_HEADER_SIZE) {
Expand Down Expand Up @@ -113,8 +144,23 @@ decode_dns(uint8_t const * pkt, uint32_t const len, dns* dns)
s_dns_stats.dns_tooshort++;
return -1;
}
// FIXME: Store this value?
uint16_t name = ntohs(*(uint16_t *)ptr);

// The "name" appears to be a partial label, but I can't find that
// documented in rfc1035, more testing is needed.
std::string name;
if (IS_SET(ptr[0], 0xC0)) {
uint8_t off = ptr[1];
uint8_t const* label = &pkt[off];
uint8_t label_len = *label;
while(label[0] != 0)
{
label++;
name.append(reinterpret_cast<char const*>(label), label_len);
name.append(".");
label += label_len;
}
}

ptr += 2;
remaining_len -= 2;

Expand Down Expand Up @@ -150,43 +196,25 @@ decode_dns(uint8_t const * pkt, uint32_t const len, dns* dns)
return -1;
}

const uint8_t *rdata = ptr;
ptr += rdlength;
remaining_len -= rdlength;

// Store answer information (assuming a structure in Packet to store this information)
// Store answer information (assuming a structure in Packet to store
// this information)
a->dns_atype = atype;
a->dns_aclass = aclass;
a->dns_ttl = ttl;

// Parse rdata
while (rdata < ptr)
if (atype == 1 || atype == 28)
{
uint16_t us = *reinterpret_cast<uint16_t const*>(rdata);
if (us == name)
{
rdata += 2;
rdlength -= 2;
continue;
}

uint8_t len = 0;
if (rdlength >= 1)
{
len = *rdata;
rdata += 1;
}
// abort if len == 0 && rdatalength > 0 // ANOMALY?

len = rdlength > len ? len : rdlength;

if (len)
{
a->data.append(reinterpret_cast<char const*>(rdata), len);
a->data.append(".");
}
rdata += len;
a->data.append(reinterpret_cast<char const*>(ptr), rdlength);
}
else
{
// Parse rdata
decode_label(pkt, ptr, a->data);
}

//const uint8_t *rdata = ptr;
ptr += rdlength;
remaining_len -= rdlength;
}

return 0;
Expand Down

0 comments on commit 5cbca2f

Please sign in to comment.