aboutsummaryrefslogtreecommitdiff
path: root/src/dns.h
blob: c2d6d18137b5d2d90ba3307f615a784c283f3650 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
#pragma once

#include <stdint.h>
#include <stdlib.h>
#include <string.h>

//TODO remove
#include <stdio.h>

/**
 * Data is COPIED
 * */
struct dns_header;

/**
 * Data is REFERENCED
 * */
struct dns_question;

/**
 * Data is REFERENCED
 * */
struct dns_answer;

/**
 * DNS Message struct
 *
 * A initialized instance is only valid as long as
 * the buffer used to create it remains unchanged
 * */
struct dns_message;

struct dns_header {
	uint16_t id;

	uint8_t QR;	//Query:0 Reply:1
	uint8_t OPCODE;	//Query:0 Iquery:1 Status:2
	uint8_t AA;	//Authorative answer
	uint8_t TC;	//Truncation
	uint8_t RD;	//Recursion Desired
	uint8_t RA;	//Recursion Available
	uint8_t Z;	//Unused
	uint8_t RCODE;	//Response Code

	uint16_t question_count;
	uint16_t answer_count;
	uint16_t authorative_count;
	uint16_t additional_count;
};

struct dns_question {
	const char* qname;
	const uint16_t* qtype;
	uint16_t* qclass;
};

struct dns_answer {
	char* name; //in qname format
	uint16_t* type;
	uint16_t* class;
	uint32_t* ttl;
	uint16_t* rdlength;
	char* rdata;
};

struct dns_message {
	struct dns_header header;

	int question_count;
	struct dns_question* question;

	int answer_count;
	struct dns_answer* answer;
};

/**
 * Parse the packet in _buffer and populate the dns_message struct
 * Struct may still be written to on failure but contents are invalid
 * returns: 0 on success, !=0 on failure
 * */
int dns_parse_packet ( char* _buffer, int _bufflen, struct dns_message* _msg );

/**
 * Convert a null terminated string containing a 
 * fqdn (eg server.example.com) to the binary format used by DNS records
 * ( [6]server[7]example[3]com[0] )
 * returns: length of string in _sink, < 0 on failure
 * _sink might not be terminated on error.
 * */
int fqdn_to_qname( char* _source, int _sourcelen, char* _sink, int _sinklen );

/**
 * Convert a QNAME back to a FQDN, reversing fqdn_to_qname( )
 * returns: length of string in _sink, < 0 on failure
 * _sink may still be altered in failed attempts, but not terminated.
 * */
int qname_to_fqdn( char* _source, int _sourcelen, char* _sink, int _sinklen );

/**
 * Check a QNAME and get length
 * returns: length of QNAME including NULL-byte at the end, < 0 on error
 * */
int qname_check( char* _source, int _sourcelen );