summaryrefslogtreecommitdiff
path: root/include/dns_decoder.h
blob: 3892d12f91428f8c39fc021b05d4b7fd469e3ffe (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
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
/*
**********************************************************************************************
*	File: dns_decoder.h
*   Description: dns decoder api
*	Authors: Liu XueLi <[email protected]>
*	Date:    2024-02-07
*   Copyright: (c) Since 2022 Geedge Networks, Ltd. All rights reserved.
***********************************************************************************************
*/

#pragma once

#ifdef __cplusplus
extern "C"
{
#endif

#include <stdint.h>
#include <linux/limits.h>
#include <stddef.h>

#define DNS_MESSAGE_TOPIC	"TOPIC_DNS"

#define DNS_NAME_MAX (NAME_MAX + 1)
// #define HINFO_NAME_MAX (40 + 1)      /* https://www.ietf.org/rfc/rfc1010.txt */

#define DNS_CLASS_UNKNOWN	0
#define DNS_CLASS_IN		1
#define DNS_CLASS_CS		2
#define DNS_CLASS_CH		3
#define DNS_CLASS_HS		4
#define DNS_CLASS_ANY		255

/* RR(resource record) type, defined in https://www.ietf.org/rfc/rfc1035.txt */
enum dns_rr_type
{
	DNS_RR_TYPE_A = 1,
	DNS_RR_TYPE_NS,
	DNS_RR_TYPE_MD,           /* Obsolete - use MX, rfc973 */
	DNS_RR_TYPE_MF,           /* Obsolete - use MX, rfc973 */
	DNS_RR_TYPE_CNAME,
	DNS_RR_TYPE_SOA,
	DNS_RR_TYPE_MB,           /* EXPERIMENTAL, rfc883,rfc2505 */
	DNS_RR_TYPE_MG,           /* EXPERIMENTAL, rfc883,rfc2505 */
	DNS_RR_TYPE_MR,           /* EXPERIMENTAL, rfc883 */
	DNS_RR_TYPE_NULL,         /* EXPERIMENTAL, rfc1035 */
	DNS_RR_TYPE_WKS,          /* Not to be relied upon, rfc1123 */
	DNS_RR_TYPE_PTR,
	DNS_RR_TYPE_HINFO,
	DNS_RR_TYPE_MINFO,
	DNS_RR_TYPE_MX,
	DNS_RR_TYPE_TXT,
	DNS_RR_TYPE_RP,
	DNS_RR_TYPE_ISDN = 20,
	DNS_RR_TYPE_AAAA = 28,     /* dns_ipv6 */
	DNS_RR_TYPE_SRV = 33,
	DNS_RR_TYPE_DNAME = 39,
	DNS_RR_TYPE_OPT = 41,
	DNS_RR_TYPE_DS = 43,
	DNS_RR_TYPE_RRSIG = 46,
	DNS_RR_TYPE_NSEC,
	DNS_RR_TYPE_DNSKEY,
	DNS_RR_TYPE_NSEC3 = 50,
	DNS_RR_TYPE_NSEC3PARAM,
	DNS_RR_TYPE_HTTPS = 65,
	DNS_RR_TYPE_AXFR = 252,
	DNS_RR_TYPE_MAILB,
	DNS_RR_TYPE_MAILA,          /* Obsolete - see MX */
	DNS_RR_TYPE_ANY,
	DNS_RR_TYPE_DLV = 32769,    /* DSNSEC Lokkaside Validation */
	DNS_RR_TYPE_UNKNOWN = 65534
};

struct dstring
{
	size_t value_sz;
	uint8_t value[DNS_NAME_MAX];
};

struct rdata_hinfo
{
	struct dstring os;
	struct dstring cpu;
};

struct rdata_minfo
{
	struct dstring rmailbx;
	struct dstring emailbx;
};

struct rdata_mx
{
	uint16_t preference;
	struct dstring exchange;
};

struct rdata_soa
{
	struct dstring mname;
	struct dstring rname;
	uint32_t serial;
	uint32_t refresh;
	uint32_t retry;
	uint32_t expire;
	uint32_t minimum;
};

struct rdata_rp
{
	struct dstring txt_rr;
	struct dstring mailbox;
};

struct rdata_wks
{
	uint8_t protocol;
	uint32_t addr;
	uint32_t size;
	uint8_t *bitmap;
};

struct rdata_srv
{
	uint16_t priority;
	uint16_t weight;
	uint16_t port;
	struct dstring target;
};

struct rdata_ds
{
	uint16_t key_tag;
	uint8_t algo;
	uint8_t digest_type;
	uint32_t digest_len;
	uint8_t *digest;
};

struct rdata_rrsig
{
	uint16_t type_covered;
	uint8_t algo;
	uint8_t labels;
	uint32_t original_ttl;
	uint32_t sig_expiration;
	uint32_t sig_inception;
	uint16_t key_tag;
	uint32_t signature_len;
	uint8_t *signature;
	struct dstring signer_name;
};

struct rdata_nsec
{
	uint16_t maps_len;
	struct dstring next_domain;
	struct dstring type_bit_maps;
};

struct rdata_dnskey
{
	uint16_t flags;
	uint8_t protocol;
	uint8_t algo;
	uint32_t public_key_len;
	uint8_t *public_key; 
};

struct rdata_nsec3
{
	uint8_t hash_algo;
	uint8_t flags;
	uint8_t salt_len;
	uint8_t hash_len;
	uint16_t iteration;
	uint16_t maps_len;
	uint8_t *salt_value;
	uint8_t *next_hash_owner;
	struct dstring type_bit_maps;
};

struct rdata_nsec3param
{
	uint8_t hash_algo;
	uint8_t flags;
	uint8_t salt_len;
	uint16_t iteration;
	uint8_t *salt_value;
};

/* rr is short for resource record */
struct dns_resource_record
{
	struct dstring qname;
	enum dns_rr_type type;
	uint16_t rr_class;
	uint32_t ttl;		/* 1byte: extended RCODE; 1byte: version; 2bytes: Z(upper bit) if type is OPT */
	uint16_t rdlength;
	union
	{

		struct dstring cname;
		struct dstring mb;
		struct dstring md;
		struct dstring mf;
		struct dstring mg;
		struct dstring mr;
		struct dstring ns;
		struct dstring ptr;
		struct dstring a;
		struct dstring aaaa;
		struct dstring dname;
		struct dstring isdn;
		struct dstring unknown;

		struct dstring txt;
		struct dstring null;

		struct rdata_hinfo hinfo;
		struct rdata_minfo minfo;
		struct rdata_mx mx;
		struct rdata_soa soa;
		struct rdata_rp rp;
		struct rdata_wks wks;
		struct rdata_srv srv;
		struct rdata_ds ds;
		struct rdata_rrsig rrsig;
		struct rdata_nsec nsec;
		struct rdata_dnskey dnskey;
		struct rdata_nsec3 nsec3;
		struct rdata_nsec3param nsec3param;
		struct dstring string;
	} rdata;
};

struct dns_message;


/*.
	First call DNS_MESSAGE_TRANSACTION_BEGIN to create the transaction, 
	then publish the transaction's DNS_MESSAGE_QUERY/DNS_MESSAGE_RESPONSE, 
	and finally call DNS_MESSAGE_TRANSACTION_END to release the transaction.
*/
enum dns_message_type
{
	DNS_MESSAGE_QUERY=1,
	DNS_MESSAGE_RESPONSE,
	DNS_MESSAGE_TRANSACTION_BEGIN,
	DNS_MESSAGE_TRANSACTION_END,
    DNS_MESSAGE_MAX
};

enum dns_message_type dns_message_type_get(struct dns_message *msg);

struct dns_flag
{
    uint8_t qr:1;
	uint8_t opcode:4;
	uint8_t aa:1;
	uint8_t tc:1;
	uint8_t rd:1;
	uint8_t ra:1;
	uint8_t z:3;
	uint8_t rcode:4;
};

struct dns_query_question
{
	enum dns_rr_type qtype;
	uint16_t qclass;
	size_t qname_sz;
	uint8_t qname[DNS_NAME_MAX];
};

int32_t dns_message_transaction_index_get(struct dns_message *msg);

int32_t dns_message_header_id_get(struct dns_message *msg);
struct dns_flag *dns_message_header_flag_get0(struct dns_message *msg);
void dns_message_question_get0(struct dns_message *msg, struct dns_query_question **question, uint16_t *n_question);
void dns_message_answer_resource_record_get0(struct dns_message *msg, struct dns_resource_record **answer_rr, uint16_t *n_answer_rr);
void dns_message_authority_resource_record_get0(struct dns_message *msg, struct dns_resource_record **authority_rr, uint16_t *n_authority_rr);
void dns_message_additional_resource_record_get0(struct dns_message *msg, struct dns_resource_record **additional_rr, uint16_t *n_additional_rr);

#ifdef __cplusplus
}
#endif