diff --git a/cmake-build-debug/.ninja_deps b/cmake-build-debug/.ninja_deps index 45aca46..8aa5bec 100644 Binary files a/cmake-build-debug/.ninja_deps and b/cmake-build-debug/.ninja_deps differ diff --git a/cmake-build-debug/.ninja_log b/cmake-build-debug/.ninja_log index b820d2b..2168de0 100644 --- a/cmake-build-debug/.ninja_log +++ b/cmake-build-debug/.ninja_log @@ -59,3 +59,5 @@ 7309 7612 1698284273630763380 insane_dns ff5ae500893d0be1 5 7368 1698284653019154297 CMakeFiles/insane_dns.dir/src/main.cpp.o 727da43cdbc82421 7369 7621 1698284653283151767 insane_dns ff5ae500893d0be1 +2 2997 1698338548693635693 CMakeFiles/insane_dns.dir/src/main.cpp.o 727da43cdbc82421 +2997 3087 1698338548789636298 insane_dns ff5ae500893d0be1 diff --git a/cmake-build-debug/CMakeFiles/insane_dns.dir/src/main.cpp.o b/cmake-build-debug/CMakeFiles/insane_dns.dir/src/main.cpp.o index dc6a200..38e0176 100644 Binary files a/cmake-build-debug/CMakeFiles/insane_dns.dir/src/main.cpp.o and b/cmake-build-debug/CMakeFiles/insane_dns.dir/src/main.cpp.o differ diff --git a/cmake-build-debug/Testing/Temporary/LastTest.log b/cmake-build-debug/Testing/Temporary/LastTest.log index 56fb8bd..b6a4e32 100644 --- a/cmake-build-debug/Testing/Temporary/LastTest.log +++ b/cmake-build-debug/Testing/Temporary/LastTest.log @@ -1,3 +1,3 @@ -Start testing: Oct 25 21:44 EDT +Start testing: Oct 26 12:42 EDT ---------------------------------------------------------- -End testing: Oct 25 21:44 EDT +End testing: Oct 26 12:42 EDT diff --git a/cmake-build-debug/insane_dns b/cmake-build-debug/insane_dns index 4b0d0b5..09b73e5 100755 Binary files a/cmake-build-debug/insane_dns and b/cmake-build-debug/insane_dns differ diff --git a/include/insane_dns/constants.h b/include/insane_dns/constants.h new file mode 100644 index 0000000..9654404 --- /dev/null +++ b/include/insane_dns/constants.h @@ -0,0 +1,30 @@ +/* + * Global constants file. + * Copyright (C) 2023 Brett Terpstra + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef INSANE_DNS_CONSTANTS_H +#define INSANE_DNS_CONSTANTS_H + +/* + * -------------------------------------------- + * | Magic Number Constants | + * -------------------------------------------- + */ +/** DNS header data offset. This is the first byte that isn't a header value (should be question label length octet) */ +static constexpr size_t DNS_HEADER_END = 12; + +#endif //INSANE_DNS_CONSTANTS_H diff --git a/include/insane_dns/util.h b/include/insane_dns/util.h new file mode 100644 index 0000000..73b0cb6 --- /dev/null +++ b/include/insane_dns/util.h @@ -0,0 +1,112 @@ +/* + * BLT Memory Util for parsing DNS packets. + * This software is unlikely to become part of BLT main but is provided under the BLT license (GPL 3). + * Copyright (C) 2023 Brett Terpstra + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef INSANE_DNS_UTIL_H +#define INSANE_DNS_UTIL_H + +#include + +namespace blt +{ + + /** + * Basic parser for processing strings of bytes received from UDP sockets. This class provides a simple interface for efficiently copying the + * big endian bytes from the network into the little endian bytes required by x86 processors. The class also provides basic safety guarantees + * in that the program will halt execution if reading the bytes would overflow the internal buffer. + */ + class byte_reader + { + private: + unsigned char* _data; + const size_t _size; + mutable size_t _current_byte = DNS_HEADER_END; + public: + explicit byte_reader(unsigned char* data, size_t size): _data(data), _size(size) + {} + + /** + * Read the next byte in the data stream then increment the internal counter by 1 + * @return the next byte in the array + */ + inline unsigned char& next() const + { + BLT_ASSERT(_current_byte < _size); + return _data[_current_byte++]; + } + + /** + * Reads data into the provided template parameter, reordering the byte into the correct little endian format + * @tparam T type to read (deduction is automatic) + * @param t variable reference to read into + */ + template + inline void to(T& t) const + { + BLT_ASSERT(_current_byte + sizeof(T) <= _size); + // I hate little endian. I hate dealing with converting between endianness + // it is very easy to do it very slowly + // So I made BLT provide a simple interface to convert between bytes dependent on the platform + // for small integral types (16, 32, and 64) it will compile to 3 instructions using compiler intrinsics. + // Larger POD types are supported but will use std::reverse and therefore be slow. + blt::mem::fromBytes(&_data[_current_byte], t); + skip(sizeof(T)); + } + + /** + * Copy from the internal data buffer, advancing the internal stream, into the provided unsigned char array. *No reordering is done* + * @param out character array to write to + * @param size number of bytes to copy + */ + inline void copy(unsigned char*& out, size_t size) const + { + BLT_ASSERT(_current_byte + size < _size); + std::memcpy(out, &_data[_current_byte], size); + skip(size); + } + + /** + * Skip bytes in the data stream, useful for skipping sections of the DNS packet we may not care about. + * @param s number of bytes to skip. + */ + inline void skip(size_t s = 1) const + { + _current_byte += s; + } + + /** + * @return 1 past the last byte we wrote to, otherwise known as the next byte we will be writing to. + */ + inline size_t last() const + { + return _current_byte; + } + + /** + * @return a pointer to a location in the internal buffer starting at last() + */ + inline unsigned char* from() + { + BLT_ASSERT(_current_byte < _size); + return &_data[_current_byte]; + } + }; + +} + +#endif //INSANE_DNS_UTIL_H diff --git a/src/main.cpp b/src/main.cpp index d5c4046..be98047 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -17,37 +17,63 @@ #include #include #include "ip.h" +#include "insane_dns/util.h" -/** +/* * ---------------------------- * | CONFIG | * ---------------------------- */ -// should we strictly match results? ie block *wikipedia.org* or just wikipedia.org? +/** should we strictly match results? ie block `*wikipedia.org*` or just `wikipedia.org`? */ static constexpr bool STRICT_MATCHING = false; -// true -> only match A records ; false -> match any named record (configure with NON_STRICT_REPLACE_ALL) -static constexpr bool STRICT_FILTERING = false; -// true -> match all records ; false -> match only records we might want to replace (A, AAAA, CNAME) -static constexpr bool NON_STRICT_REPLACE_ALL = true; -// DNS server to use for forwarding to / resolving DNS requests +/** DNS server to use for forwarding to / resolving DNS requests */ static inline constexpr std::string DNS_SERVER_IP() { return "8.8.8.8"; } -// replacement IP address. Make sure this is a 4 octet string seperated by . +/** replacement IP address. Make sure this is a 4 octet string seperated by `.` */ static inline constexpr IPAddress REPLACEMENT_IP() { return {"139.57.100.6"}; } +/** + * List of disallowed domains. + * Note: if you are using STRICT_MATCHING=false it will not match to the root domain. + * Eg it will match `*en.wikipedia.org*` NOT `*wikipedia.org*` + */ static const std::unordered_set DISALLOWED_DOMAINS{ "en.wikipedia.org", "tpgc.me", "zombo.com" }; +/* + * ----------------------------------- + * | Do Not Change | + * ----------------------------------- + */ +// these features were planned but not added because I realized you guys won't care or give extra marks which broke my obsession with it +// so uhh don't change em otherwise the code will break :3 + +/** true -> only match A records ; false -> match any named record (configure with NON_STRICT_REPLACE_ALL) */ +static constexpr bool STRICT_FILTERING = true; +/** true -> match all records ; false -> match only records we might want to replace (A, AAAA, CNAME) */ +static constexpr bool NON_STRICT_REPLACE_ALL = true; + +// was going to add TCP and ad blocking support +// that also isn't going to happen now. +/** list of web address to download the ad block lists from */ +static constexpr std::vector BLOCK_LISTS{}; +/** true -> block ad DNS requests ; false -> do nothing */ +static constexpr bool BLOCK_ADS = false; +/** true -> send back the REPLACEMENT_IP() ; false -> send back a fail state in the DNS request. */ +static constexpr bool REDIRECT_ADS = true; + +// 5F826B + // DNS data contains: // 2 bytes for transaction id // 2 bytes for flags @@ -71,57 +97,6 @@ static const std::unordered_set DISALLOWED_DOMAINS{ // 2 byte for length of data // (lengthy) byte for data -class byte_reader -{ - private: - unsigned char* data; - mutable size_t current_byte = 0; - public: - explicit byte_reader(unsigned char* data): data(data) - { - reset(); - } - - inline void reset() const - { - // magic number for end of header - current_byte = 12; - } - - inline unsigned char& next() const - { - return data[current_byte++]; - } - - template - inline void to(T& t) const - { - blt::mem::fromBytes(&data[current_byte], t); - skip(sizeof(T)); - } - - inline void copy(unsigned char*& out, size_t size) const - { - std::memcpy(out, &data[current_byte], size); - current_byte += size; - } - - inline void skip(size_t s = 1) const - { - current_byte += s; - } - - inline size_t last() const - { - return current_byte; - } - - inline unsigned char* from() - { - return &data[current_byte]; - } -}; - class send_buffer; class question @@ -376,7 +351,7 @@ int main() uint16_t num_of_answers; blt::mem::fromBytes(&mod_recv_buf[6], num_of_answers); - byte_reader reader2(mod_recv_buf.data()); + byte_reader reader2(mod_recv_buf.data(), mod_recv_buf.size()); BLT_INFO("Bytes answered %d with %d answers", out_bytes, num_of_answers);