1/*
2 * Copyright (c) 2009, 2012-2015, 2018 by Farsight Security, Inc.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *    http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#ifndef WDNS_H
18#define WDNS_H
19
20#ifdef __cplusplus
21extern "C" {
22#endif
23
24#include <stdbool.h>
25#include <stdint.h>
26#include <stdio.h>
27
28/* Constants. */
29
30#define WDNS_LEN_HEADER		12
31#define WDNS_MAXLEN_NAME	255
32
33#define WDNS_MSG_SEC_QUESTION	0
34#define WDNS_MSG_SEC_ANSWER	1
35#define WDNS_MSG_SEC_AUTHORITY	2
36#define WDNS_MSG_SEC_ADDITIONAL	3
37#define WDNS_MSG_SEC_MAX	4
38
39#define WDNS_PRESLEN_NAME	1025
40#define WDNS_PRESLEN_TYPE_A	16
41#define WDNS_PRESLEN_TYPE_AAAA	46
42
43#define WDNS_OP_QUERY		0
44#define WDNS_OP_IQUERY		1
45#define WDNS_OP_STATUS		2
46#define WDNS_OP_NOTIFY		4
47#define WDNS_OP_UPDATE		5
48
49#define WDNS_R_NOERROR		0
50#define WDNS_R_FORMERR		1
51#define WDNS_R_SERVFAIL		2
52#define WDNS_R_NXDOMAIN		3
53#define WDNS_R_NOTIMP		4
54#define WDNS_R_REFUSED		5
55#define WDNS_R_YXDOMAIN		6
56#define WDNS_R_YXRRSET		7
57#define WDNS_R_NXRRSET		8
58#define WDNS_R_NOTAUTH		9
59#define WDNS_R_NOTZONE		10
60#define WDNS_R_BADVERS		16
61
62#define WDNS_CLASS_IN		1
63#define WDNS_CLASS_CH		3
64#define WDNS_CLASS_HS		4
65#define WDNS_CLASS_NONE		254
66#define WDNS_CLASS_ANY		255
67
68#define WDNS_TYPE_A		1
69#define WDNS_TYPE_NS		2
70#define WDNS_TYPE_MD		3
71#define WDNS_TYPE_MF		4
72#define WDNS_TYPE_CNAME		5
73#define WDNS_TYPE_SOA		6
74#define WDNS_TYPE_MB		7
75#define WDNS_TYPE_MG		8
76#define WDNS_TYPE_MR		9
77#define WDNS_TYPE_NULL		10
78#define WDNS_TYPE_WKS		11
79#define WDNS_TYPE_PTR		12
80#define WDNS_TYPE_HINFO		13
81#define WDNS_TYPE_MINFO		14
82#define WDNS_TYPE_MX		15
83#define WDNS_TYPE_TXT		16
84#define WDNS_TYPE_RP		17
85#define WDNS_TYPE_AFSDB		18
86#define WDNS_TYPE_X25		19
87#define WDNS_TYPE_ISDN		20
88#define WDNS_TYPE_RT		21
89#define WDNS_TYPE_NSAP		22
90#define WDNS_TYPE_NSAP_PTR	23
91#define WDNS_TYPE_SIG		24
92#define WDNS_TYPE_KEY		25
93#define WDNS_TYPE_PX		26
94#define WDNS_TYPE_GPOS		27
95#define WDNS_TYPE_AAAA		28
96#define WDNS_TYPE_LOC		29
97#define WDNS_TYPE_NXT		30
98#define WDNS_TYPE_EID		31
99#define WDNS_TYPE_NIMLOC	32
100#define WDNS_TYPE_SRV		33
101#define WDNS_TYPE_ATMA		34
102#define WDNS_TYPE_NAPTR		35
103#define WDNS_TYPE_KX		36
104#define WDNS_TYPE_CERT		37
105#define WDNS_TYPE_A6		38
106#define WDNS_TYPE_DNAME		39
107#define WDNS_TYPE_SINK		40
108#define WDNS_TYPE_OPT		41
109#define WDNS_TYPE_APL		42
110#define WDNS_TYPE_DS		43
111#define WDNS_TYPE_SSHFP		44
112#define WDNS_TYPE_IPSECKEY	45
113#define WDNS_TYPE_RRSIG		46
114#define WDNS_TYPE_NSEC		47
115#define WDNS_TYPE_DNSKEY	48
116#define WDNS_TYPE_DHCID		49
117#define WDNS_TYPE_NSEC3		50
118#define WDNS_TYPE_NSEC3PARAM	51
119#define WDNS_TYPE_TLSA		52
120/* Unassigned: 53 - 54 */
121#define WDNS_TYPE_HIP		55
122#define WDNS_TYPE_NINFO		56
123#define WDNS_TYPE_RKEY		57
124#define WDNS_TYPE_TALINK	58
125#define WDNS_TYPE_CDS		59
126#define WDNS_TYPE_CDNSKEY	60
127#define WDNS_TYPE_OPENPGPKEY	61
128#define WDNS_TYPE_CSYNC		62
129/* Unassigned: 63 - 98 */
130#define WDNS_TYPE_SPF		99
131#define WDNS_TYPE_UINFO		100
132#define WDNS_TYPE_UID		101
133#define WDNS_TYPE_GID		102
134#define WDNS_TYPE_UNSPEC	103
135#define WDNS_TYPE_NID		104
136#define WDNS_TYPE_L32		105
137#define WDNS_TYPE_L64		106
138#define WDNS_TYPE_LP		107
139#define WDNS_TYPE_EUI48		108
140#define WDNS_TYPE_EUI64		109
141/* Unassigned: 110 - 248 */
142#define WDNS_TYPE_TKEY		249
143#define WDNS_TYPE_TSIG		250
144#define WDNS_TYPE_IXFR		251
145#define WDNS_TYPE_AXFR		252
146#define WDNS_TYPE_MAILB		253
147#define WDNS_TYPE_MAILA		254
148#define WDNS_TYPE_ANY		255
149#define WDNS_TYPE_URI		256
150#define WDNS_TYPE_CAA		257
151/* Unassigned: 258 - 32767 */
152#define WDNS_TYPE_TA		32768
153#define WDNS_TYPE_DLV		32769
154/* Unassigned: 32770 - 65279 */
155/* Private use: 65280 - 65534 */
156/* Reserved: 65535 */
157
158#define WDNS_LIBRARY_VERSION "@WDNS_VERSION@"
159#define WDNS_LIBRARY_VERSION_NUMBER @WDNS_MAJOR_VERSION@ * 1000000L + @WDNS_MINOR_VERSION@ * 1000L + @WDNS_PATCHLEVEL_VERSION@
160
161/* Macros. */
162
163#define WDNS_FLAGS_QR(msg)		((((msg).flags) >> 15) & 0x01)
164#define WDNS_FLAGS_OPCODE(msg)		((((msg).flags) >> 11) & 0x0f)
165#define WDNS_FLAGS_AA(msg)		((((msg).flags) >> 10) & 0x01)
166#define WDNS_FLAGS_TC(msg)		((((msg).flags) >> 9) & 0x01)
167#define WDNS_FLAGS_RD(msg)		((((msg).flags) >> 8) & 0x01)
168#define WDNS_FLAGS_RA(msg)		((((msg).flags) >> 7) & 0x01)
169#define WDNS_FLAGS_Z(msg)		((((msg).flags) >> 6) & 0x01)
170#define WDNS_FLAGS_AD(msg)		((((msg).flags) >> 5) & 0x01)
171#define WDNS_FLAGS_CD(msg)		((((msg).flags) >> 4) & 0x01)
172#define WDNS_FLAGS_RCODE(msg)		((msg).rcode)
173
174#if defined(__GNUC__)
175# define WDNS_WARN_UNUSED_RESULT	__attribute__ ((warn_unused_result))
176#else
177# define WDNS_WARN_UNUSED_RESULT
178#endif
179
180/* Data structures and definitions. */
181
182typedef enum {
183	wdns_res_success,
184	wdns_res_failure,
185	wdns_res_invalid_compression_pointer,
186	wdns_res_invalid_length_octet,
187	wdns_res_invalid_opcode,
188	wdns_res_invalid_rcode,
189	wdns_res_len,
190	wdns_res_malloc,
191	wdns_res_name_len,
192	wdns_res_name_overflow,
193	wdns_res_out_of_bounds,
194	wdns_res_overflow,
195	wdns_res_parse_error,
196	wdns_res_qdcount,
197	wdns_res_unknown_opcode,
198	wdns_res_unknown_rcode,
199} wdns_res;
200
201typedef struct {
202	uint8_t			len;
203	uint8_t			*data;
204} wdns_name_t;
205
206typedef struct {
207	uint16_t		len;
208	uint8_t			data[];
209} wdns_rdata_t;
210
211typedef struct {
212	uint32_t		rrttl;
213	uint16_t		rrtype;
214	uint16_t		rrclass;
215	wdns_name_t		name;
216	wdns_rdata_t		*rdata;
217} wdns_rr_t;
218
219typedef struct {
220	uint32_t		rrttl;
221	uint16_t		rrtype;
222	uint16_t		rrclass;
223	uint16_t		n_rdatas;
224	wdns_name_t		name;
225	wdns_rdata_t		**rdatas;
226} wdns_rrset_t;
227
228typedef struct {
229	uint16_t		n_rrs;
230	uint16_t		n_rrsets;
231	wdns_rr_t		*rrs;
232	wdns_rrset_t		*rrsets;
233} wdns_rrset_array_t;
234
235typedef struct {
236	bool			present;
237	uint8_t			version;
238	uint16_t		flags;
239	uint16_t		size;
240	wdns_rdata_t		*options;
241} wdns_edns_t;
242
243typedef struct {
244	wdns_rrset_array_t	sections[4];
245	wdns_edns_t		edns;
246	uint16_t		id;
247	uint16_t		flags;
248	uint16_t		rcode;
249} wdns_message_t;
250
251/* Function prototypes. */
252
253typedef void (*wdns_callback_name)(wdns_name_t *name, void *user);
254
255/* Functions for converting objects to presentation format strings. */
256
257const char *	wdns_res_to_str(wdns_res res);
258const char *	wdns_opcode_to_str(uint16_t dns_opcode);
259const char *	wdns_rcode_to_str(uint16_t dns_rcode);
260const char *	wdns_rrclass_to_str(uint16_t dns_class);
261const char *	wdns_rrtype_to_str(uint16_t dns_type);
262size_t		wdns_domain_to_str(const uint8_t *src, size_t src_len, char *dst);
263
264char *		wdns_message_to_str(wdns_message_t *m);
265char *		wdns_rrset_array_to_str(wdns_rrset_array_t *a, unsigned sec);
266char *		wdns_rrset_to_str(wdns_rrset_t *rrset, unsigned sec);
267char *		wdns_rr_to_str(wdns_rr_t *rr, unsigned sec);
268char *		wdns_rdata_to_str(const uint8_t *rdata, uint16_t rdlen,
269				  uint16_t rrtype, uint16_t rrclass);
270
271/* Functions for converting presentation format strings to objects. */
272
273WDNS_WARN_UNUSED_RESULT
274wdns_res
275wdns_str_to_name(const char *str, wdns_name_t *name);
276
277WDNS_WARN_UNUSED_RESULT
278wdns_res
279wdns_str_to_name_case(const char *str, wdns_name_t *name);
280
281wdns_res
282wdns_str_to_rcode(const char *str, uint16_t *out);
283
284uint16_t
285wdns_str_to_rrtype(const char *str);
286
287uint16_t
288wdns_str_to_rrclass(const char *str);
289
290wdns_res
291wdns_str_to_rdata(const char * str, uint16_t rrtype, uint16_t rrclass,
292		   uint8_t **rdata, size_t *rdlen);
293
294/* Comparison functions. */
295
296bool	wdns_compare_rr_rrset(const wdns_rr_t *rr, const wdns_rrset_t *rrset);
297
298/* Functions for clearing wdns objects. */
299
300void	wdns_clear_message(wdns_message_t *m);
301void	wdns_clear_rr(wdns_rr_t *rr);
302void	wdns_clear_rrset(wdns_rrset_t *rrset);
303void	wdns_clear_rrset_array(wdns_rrset_array_t *a);
304
305/* Functions for printing formatted output. */
306
307void	wdns_print_message(FILE *fp, wdns_message_t *m);
308void	wdns_print_rr(FILE *fp, wdns_rr_t *rr, unsigned sec);
309void	wdns_print_rrset(FILE *fp, wdns_rrset_t *rrset, unsigned sec);
310void	wdns_print_rrset_array(FILE *fp, wdns_rrset_array_t *a, unsigned sec);
311
312/* Utility functions. */
313
314size_t	wdns_skip_name(const uint8_t **data, const uint8_t *eod);
315
316wdns_res
317wdns_copy_uname(const uint8_t *p, const uint8_t *eop, const uint8_t *src,
318		uint8_t *dst, size_t *sz);
319
320wdns_res
321wdns_len_uname(const uint8_t *p, const uint8_t *eop, size_t *sz);
322
323wdns_res
324wdns_sort_rrset(wdns_rrset_t *);
325
326wdns_res
327wdns_unpack_name(const uint8_t *p, const uint8_t *eop, const uint8_t *src,
328		 uint8_t *dst, size_t *sz);
329
330wdns_res
331wdns_count_labels(wdns_name_t *name, size_t *nlabels);
332
333wdns_res
334wdns_is_subdomain(wdns_name_t *n0, wdns_name_t *n1, bool *is_subdomain);
335
336wdns_res
337wdns_file_load_names(const char *fname, wdns_callback_name cb, void *user);
338
339wdns_res
340wdns_left_chop(wdns_name_t *name, wdns_name_t *chop);
341
342WDNS_WARN_UNUSED_RESULT
343wdns_res
344wdns_reverse_name(const uint8_t *name, size_t len_name, uint8_t *rev_name);
345
346/**
347 * Retrieve the semantic library version as a string. This function was
348 * Introduced in version 0.10.0.
349 */
350const char *wdns_get_version(void);
351
352/**
353 * Retrieve the semantic library version as a packed integer. The number is a
354 * combination of the major, minor, and patchelevel numbers as per:
355 * MAJOR * 1000000 + MINOR * 1000 + PATCHLEVEL. This function was introduced
356 * in version 0.10.0.
357 */
358uint32_t wdns_get_version_number(void);
359
360/* Parsing functions. */
361
362wdns_res
363wdns_parse_message(wdns_message_t *m, const uint8_t *pkt, size_t len);
364
365/* Deserialization functions. */
366
367wdns_res
368wdns_deserialize_rrset(wdns_rrset_t *rrset, const uint8_t *buf, size_t sz);
369
370/* Serialization functions. */
371
372wdns_res
373wdns_serialize_rrset(const wdns_rrset_t *rrset, uint8_t *buf, size_t *sz);
374
375/* Downcasing functions. */
376
377void
378wdns_downcase_name(wdns_name_t *name);
379
380wdns_res
381wdns_downcase_rdata(wdns_rdata_t *rdata, uint16_t rrtype, uint16_t rrclass);
382
383wdns_res
384wdns_downcase_rrset(wdns_rrset_t *rrset);
385
386#ifdef __cplusplus
387}
388#endif
389
390#endif /* WDNS_H */
391