mirror of
https://github.com/mfontanini/libtins
synced 2026-01-29 21:14:28 +01:00
DNS is working. Constructor from buffer is not implemented yet.
This commit is contained in:
320
include/dns.h
320
include/dns.h
@@ -23,6 +23,8 @@
|
||||
#define __DNS_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <list>
|
||||
#include <string>
|
||||
#include "pdu.h"
|
||||
|
||||
namespace Tins {
|
||||
@@ -33,6 +35,209 @@ namespace Tins {
|
||||
RESPONSE = 1
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Query types enum.
|
||||
*/
|
||||
enum QueryType {
|
||||
A = 1,
|
||||
NS,
|
||||
MD,
|
||||
MF,
|
||||
CNAME,
|
||||
SOA,
|
||||
MB,
|
||||
MG,
|
||||
MR,
|
||||
NULL_R,
|
||||
WKS,
|
||||
PTR,
|
||||
HINFO,
|
||||
MINFO,
|
||||
MX,
|
||||
TXT,
|
||||
RP,
|
||||
AFSDB,
|
||||
X25,
|
||||
ISDN,
|
||||
RT,
|
||||
NSAP,
|
||||
NSAP_PTR,
|
||||
SIG,
|
||||
KEY,
|
||||
PX,
|
||||
GPOS,
|
||||
AAAA,
|
||||
LOC,
|
||||
NXT,
|
||||
EID,
|
||||
NIMLOC,
|
||||
SRV,
|
||||
ATMA,
|
||||
NAPTR,
|
||||
KX,
|
||||
CERT,
|
||||
A6,
|
||||
DNAM,
|
||||
SINK,
|
||||
OPT,
|
||||
APL,
|
||||
DS,
|
||||
SSHFP,
|
||||
IPSECKEY,
|
||||
RRSIG,
|
||||
NSEC,
|
||||
DNSKEY,
|
||||
DHCID,
|
||||
NSEC3,
|
||||
NSEC3PARAM
|
||||
};
|
||||
|
||||
enum QueryClass {
|
||||
IN = 1,
|
||||
CH = 3,
|
||||
HS = 4,
|
||||
ANY = 255
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Default constructor.
|
||||
*
|
||||
* This constructor initializes every field to 0.
|
||||
*/
|
||||
DNS();
|
||||
|
||||
/**
|
||||
* \brief Destructor.
|
||||
*/
|
||||
~DNS();
|
||||
|
||||
// Getters
|
||||
|
||||
/**
|
||||
* \brief Setter for the id field.
|
||||
*
|
||||
* \return uint16_t containing the value of the id field.
|
||||
*/
|
||||
uint16_t id() { return dns.id; }
|
||||
|
||||
/**
|
||||
* \brief Setter for the query response field.
|
||||
*
|
||||
* \return QRType containing the value of the query response
|
||||
* field.
|
||||
*/
|
||||
QRType type() { return static_cast<QRType>(dns.qr); }
|
||||
|
||||
/**
|
||||
* \brief Setter for the opcode field.
|
||||
*
|
||||
* \return uint8_t containing the value of the opcode field.
|
||||
*/
|
||||
uint8_t opcode() { return dns.opcode; }
|
||||
|
||||
/**
|
||||
* \brief Setter for the authoritative answer field.
|
||||
*
|
||||
* \return uint8_t containing the value of the authoritative
|
||||
* answer field.
|
||||
*/
|
||||
uint8_t authoritative_answer() { return dns.aa; }
|
||||
|
||||
/**
|
||||
* \brief Setter for the truncated field.
|
||||
*
|
||||
* \return uint8_t containing the value of the truncated field.
|
||||
*/
|
||||
uint8_t truncated() { return dns.tc; }
|
||||
|
||||
/**
|
||||
* \brief Setter for the recursion desired field.
|
||||
*
|
||||
* \return uint8_t containing the value of the recursion
|
||||
* desired field.
|
||||
*/
|
||||
uint8_t recursion_desired() { return dns.rd; }
|
||||
|
||||
/**
|
||||
* \brief Setter for the recursion available field.
|
||||
*
|
||||
* \return uint8_t containing the value of the recursion
|
||||
* available field.
|
||||
*/
|
||||
uint8_t recursion_available() { return dns.ra; }
|
||||
|
||||
/**
|
||||
* \brief Setter for the z desired field.
|
||||
*
|
||||
* \return uint8_t containing the value of the z field.
|
||||
*/
|
||||
uint8_t z() { return dns.z; }
|
||||
|
||||
/**
|
||||
* \brief Setter for the authenticated data field.
|
||||
*
|
||||
* \return uint8_t containing the value of the authenticated
|
||||
* data field.
|
||||
*/
|
||||
uint8_t authenticated_data() { return dns.ad; }
|
||||
|
||||
/**
|
||||
* \brief Setter for the checking disabled field.
|
||||
*
|
||||
* \return uint8_t containing the value of the checking
|
||||
* disabled field.
|
||||
*/
|
||||
uint8_t checking_disabled() { return dns.cd; }
|
||||
|
||||
/**
|
||||
* \brief Setter for the rcode field.
|
||||
*
|
||||
* \return uint8_t containing the value of the rcode field.
|
||||
*/
|
||||
uint8_t rcode() { return dns.rcode; }
|
||||
|
||||
/**
|
||||
* \brief Setter for the questions field.
|
||||
*
|
||||
* \return uint16_t containing the value of the questions field.
|
||||
*/
|
||||
uint16_t questions() { return dns.questions; }
|
||||
|
||||
/**
|
||||
* \brief Setter for the answers field.
|
||||
*
|
||||
* \return uint16_t containing the value of the answers field.
|
||||
*/
|
||||
uint16_t answers() { return dns.answers; }
|
||||
|
||||
/**
|
||||
* \brief Setter for the authority field.
|
||||
*
|
||||
* \return uint16_t containing the value of the authority field.
|
||||
*/
|
||||
uint16_t authority() { return dns.authority; }
|
||||
|
||||
/**
|
||||
* \brief Setter for the additional field.
|
||||
*
|
||||
* \return uint16_t containing the value of the additional field.
|
||||
*/
|
||||
uint16_t additional() { return dns.additional; }
|
||||
|
||||
/**
|
||||
* \brief Getter for the PDU's type.
|
||||
*
|
||||
* \return Returns the PDUType corresponding to the PDU.
|
||||
*/
|
||||
PDUType pdu_type() const { return PDU::DNS; }
|
||||
|
||||
/**
|
||||
* \brief The header's size
|
||||
*/
|
||||
uint32_t header_size() const;
|
||||
|
||||
// Setters
|
||||
|
||||
/**
|
||||
* \brief Setter for the id field.
|
||||
*
|
||||
@@ -114,25 +319,122 @@ namespace Tins {
|
||||
* \param new_rcode The new rcode value to be set.
|
||||
*/
|
||||
void rcode(uint8_t new_rcode);
|
||||
|
||||
// Methods
|
||||
/**
|
||||
* \brief Add a query to perform.
|
||||
*
|
||||
* \param name The name to be resolved.
|
||||
* \param type The type of this query.
|
||||
* \param qclass The class of this query.
|
||||
*/
|
||||
void add_query(const std::string &name, QueryType type, QueryClass qclass);
|
||||
|
||||
/**
|
||||
* \brief Add a query response.
|
||||
*
|
||||
* \param name The resolved name.
|
||||
* \param type The type of this answer.
|
||||
* \param qclass The class of this answer.
|
||||
* \param ttl The time-to-live of this answer.
|
||||
* \param ip The ip address of the resolved name.
|
||||
*/
|
||||
void add_answer(const std::string &name, QueryType type, QueryClass qclass,
|
||||
uint32_t ttl, uint32_t ip);
|
||||
|
||||
/**
|
||||
* \brief Add an authority record.
|
||||
*
|
||||
* \param name The resolved name.
|
||||
* \param type The type of this record.
|
||||
* \param qclass The class of this record.
|
||||
* \param ttl The time-to-live of this record.
|
||||
* \param ip The ip address of the resolved name.
|
||||
*/
|
||||
void add_authority(const std::string &name, QueryType type, QueryClass qclass,
|
||||
uint32_t ttl, uint32_t ip);
|
||||
|
||||
/**
|
||||
* \brief Add an additional record.
|
||||
*
|
||||
* \param name The resolved name.
|
||||
* \param type The type of this record.
|
||||
* \param qclass The class of this record.
|
||||
* \param ttl The time-to-live of this record.
|
||||
* \param ip The ip address of the resolved name.
|
||||
*/
|
||||
void add_additional(const std::string &name, QueryType type, QueryClass qclass,
|
||||
uint32_t ttl, uint32_t ip);
|
||||
private:
|
||||
struct dnshdr {
|
||||
uint16_t id;
|
||||
uint16_t
|
||||
qr:1,
|
||||
opcode:4,
|
||||
aa:1,
|
||||
tc:1,
|
||||
rd:1,
|
||||
ra:1,
|
||||
z:1,
|
||||
ad:1,
|
||||
tc:1,
|
||||
aa:1,
|
||||
opcode:4,
|
||||
qr:1,
|
||||
rcode:4,
|
||||
cd:1,
|
||||
rcode:4;
|
||||
uint32_t questions, answers,
|
||||
ad:1,
|
||||
z:1,
|
||||
ra:1;
|
||||
uint16_t questions, answers,
|
||||
authority, additional;
|
||||
} __attribute__((packed));
|
||||
|
||||
struct Query {
|
||||
std::string name;
|
||||
uint16_t type, qclass;
|
||||
|
||||
Query(const std::string &nm, uint16_t t, uint16_t c) :
|
||||
name(nm), type(t), qclass(c) {}
|
||||
};
|
||||
|
||||
struct ResourceRecord {
|
||||
struct {
|
||||
uint16_t type, qclass;
|
||||
uint32_t ttl;
|
||||
uint16_t dlen;
|
||||
uint32_t data;
|
||||
} __attribute__((packed)) info;
|
||||
|
||||
virtual ~ResourceRecord() {}
|
||||
uint32_t write(uint8_t *buffer) const;
|
||||
virtual uint32_t do_write(uint8_t *buffer) const = 0;
|
||||
virtual uint32_t size() const = 0;
|
||||
};
|
||||
|
||||
struct OffsetedResourceRecord : public ResourceRecord {
|
||||
uint16_t offset;
|
||||
|
||||
OffsetedResourceRecord(uint16_t off) : offset(off | 0xc0) {}
|
||||
|
||||
uint32_t do_write(uint8_t *buffer) const;
|
||||
uint32_t size() const { return sizeof(info) + sizeof(offset); }
|
||||
};
|
||||
|
||||
struct NamedResourceRecord : public ResourceRecord {
|
||||
std::string name;
|
||||
|
||||
NamedResourceRecord(const std::string &nm) : name(nm) {}
|
||||
|
||||
uint32_t do_write(uint8_t *buffer) const;
|
||||
uint32_t size() const { return sizeof(info) + name.size() + 1; }
|
||||
};
|
||||
|
||||
uint32_t find_domain_name(const std::string &dname);
|
||||
bool find_domain_name(const std::string &dname, const std::list<ResourceRecord*> &lst, uint16_t &out);
|
||||
void parse_domain_name(const std::string &dn, std::string &out);
|
||||
void write_serialization(uint8_t *buffer, uint32_t total_sz, const PDU *parent);
|
||||
void free_list(std::list<ResourceRecord*> &lst);
|
||||
uint8_t *serialize_list(const std::list<ResourceRecord*> &lst, uint8_t *buffer) const;
|
||||
ResourceRecord *make_record(const std::string &name, QueryType type, QueryClass qclass, uint32_t ttl, uint32_t ip);
|
||||
|
||||
dnshdr dns;
|
||||
uint32_t extra_size;
|
||||
std::list<Query> queries;
|
||||
std::list<ResourceRecord*> ans, arity, addit;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@@ -87,7 +87,8 @@ namespace Tins {
|
||||
DHCP,
|
||||
EAPOL,
|
||||
RC4EAPOL,
|
||||
RSNEAPOL
|
||||
RSNEAPOL,
|
||||
DNS
|
||||
};
|
||||
|
||||
/** \brief PDU constructor
|
||||
|
||||
Reference in New Issue
Block a user