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 );
|