1 /*  Copyright (C) 2021 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
2 
3     This program is free software: you can redistribute it and/or modify
4     it under the terms of the GNU General Public License as published by
5     the Free Software Foundation, either version 3 of the License, or
6     (at your option) any later version.
7 
8     This program is distributed in the hope that it will be useful,
9     but WITHOUT ANY WARRANTY; without even the implied warranty of
10     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11     GNU General Public License for more details.
12 
13     You should have received a copy of the GNU General Public License
14     along with this program.  If not, see <https://www.gnu.org/licenses/>.
15  */
16 
17 #pragma once
18 
19 #include <stdbool.h>
20 
21 #include "utils/common/params.h"
22 #include "utils/common/exec.h"
23 #include "utils/common/https.h"
24 #include "utils/common/sign.h"
25 #include "libknot/libknot.h"
26 #include "contrib/sockaddr.h"
27 
28 #if USE_DNSTAP
29 # include "contrib/dnstap/reader.h"
30 # include "contrib/dnstap/writer.h"
31 #endif // USE_DNSTAP
32 
33 /*! \brief Operation mode of kdig. */
34 typedef enum {
35 	/*!< Standard 1-message query/reply. */
36 	OPERATION_QUERY,
37 	/*!< Zone transfer (AXFR or IXFR). */
38 	OPERATION_XFR,
39 	/*!< Dump dnstap file. */
40 	OPERATION_LIST_DNSTAP,
41 } operation_t;
42 
43 /*! \brief DNS header and EDNS flags. */
44 typedef struct {
45 	/*!< Authoritative answer flag. */
46 	bool	aa_flag;
47 	/*!< Truncated flag. */
48 	bool	tc_flag;
49 	/*!< Recursion desired flag. */
50 	bool	rd_flag;
51 	/*!< Recursion available flag. */
52 	bool	ra_flag;
53 	/*!< Z flag. */
54 	bool	z_flag;
55 	/*!< Authenticated data flag. */
56 	bool	ad_flag;
57 	/*!< Checking disabled flag. */
58 	bool	cd_flag;
59 	/*!< DNSSEC OK flag. */
60 	bool	do_flag;
61 } flags_t;
62 
63 /*! \brief Basic parameters for DNS query. */
64 typedef struct query query_t; // Forward declaration due to configuration.
65 struct query {
66 	/*!< List node (for list container). */
67 	node_t		n;
68 	/*!< Reference to global config. */
69 	const query_t	*conf;
70 	/*!< Name to query on. */
71 	char		*owner;
72 	/*!< List of nameservers to query to. */
73 	list_t		servers;
74 	/*!< Local interface (optional). */
75 	srv_info_t	*local;
76 	/*!< Operation mode. */
77 	operation_t	operation;
78 	/*!< Version of ip protocol to use. */
79 	ip_t		ip;
80 	/*!< Protocol type (TCP, UDP) to use. */
81 	protocol_t	protocol;
82 	/*!< Use TCP Fast Open. */
83 	bool		fastopen;
84 	/*!< Keep TCP connection open. */
85 	bool		keepopen;
86 	/*!< Port/service to connect to. */
87 	char		*port;
88 	/*!< UDP buffer size (16unsigned + -1 uninitialized). */
89 	int32_t		udp_size;
90 	/*!< Number of UDP retries. */
91 	uint32_t	retries;
92 	/*!< Wait for network response in seconds (-1 means forever). */
93 	int32_t		wait;
94 	/*!< Ignore truncated response. */
95 	bool		ignore_tc;
96 	/*!< Class number (16unsigned + -1 uninitialized). */
97 	int32_t		class_num;
98 	/*!< Type number (16unsigned + -1 uninitialized). */
99 	int32_t		type_num;
100 	/*!< SOA serial for IXFR and NOTIFY (32unsigned + -1 uninitialized). */
101 	int64_t		serial;
102 	/*!< NOTIFY query. */
103 	bool		notify;
104 	/*!< Header flags. */
105 	flags_t		flags;
106 	/*!< Output settings. */
107 	style_t		style;
108 	/*!< IDN conversion. */
109 	bool		idn;
110 	/*!< Query for NSID. */
111 	bool		nsid;
112 	/*!< EDNS version (8unsigned + -1 uninitialized). */
113 	int16_t		edns;
114 	/*!< EDNS client cookie. */
115 	knot_edns_cookie_t cc;
116 	/*!< EDNS server cookie. */
117 	knot_edns_cookie_t sc;
118 	/*!< Repeat query after BADCOOKIE. */
119 	int		badcookie;
120 	/*!< EDNS0 padding (16unsigned + -1 ~ uninitialized, -2 ~ default, -3 ~ none). */
121 	int32_t		padding;
122 	/*!< Query alignment with EDNS0 padding (0 ~ uninitialized). */
123 	uint16_t	alignment;
124 	/*!< TLS parameters. */
125 	tls_params_t	tls;
126 	/*!< HTTPS parameters. */
127 	https_params_t	https;
128 	/*!< Transaction signature. */
129 	knot_tsig_key_t	tsig_key;
130 	/*!< EDNS client subnet. */
131 	knot_edns_client_subnet_t subnet;
132 	/*!< Lits of custom EDNS options. */
133 	list_t		edns_opts;
134 #if USE_DNSTAP
135 	/*!< Context for dnstap reader input. */
136 	dt_reader_t	*dt_reader;
137 	/*!< Context for dnstap writer output. */
138 	dt_writer_t	*dt_writer;
139 #endif // USE_DNSTAP
140 };
141 
142 /*! \brief EDNS option data. */
143 typedef struct {
144 	/*! List node (for list container). */
145 	node_t	n;
146 	/*!< OPTION-CODE field. */
147 	uint16_t code;
148 	/*!< OPTION-LENGTH field. */
149 	uint16_t length;
150 	/*!< OPTION-DATA field. */
151 	uint8_t *data;
152 } ednsopt_t;
153 
154 /*! \brief Settings for kdig. */
155 typedef struct {
156 	/*!< Stop processing - just print help, version,... */
157 	bool	stop;
158 	/*!< List of DNS queries to process. */
159 	list_t	queries;
160 	/*!< Default settings for queries. */
161 	query_t	*config;
162 } kdig_params_t;
163 
164 query_t *query_create(const char *owner, const query_t *config);
165 void query_free(query_t *query);
166 void complete_queries(list_t *queries, const query_t *conf);
167 
168 ednsopt_t *ednsopt_create(uint16_t code, uint16_t length, uint8_t *data);
169 ednsopt_t *ednsopt_dup(const ednsopt_t *opt);
170 void ednsopt_free(ednsopt_t *opt);
171 
172 void ednsopt_list_init(list_t *list);
173 void ednsopt_list_deinit(list_t *list);
174 int ednsopt_list_dup(list_t *dst, const list_t *src);
175 bool ednsopt_list_empty(const list_t *list);
176 
177 int kdig_init(kdig_params_t *params);
178 int kdig_parse(kdig_params_t *params, int argc, char *argv[]);
179 void kdig_clean(kdig_params_t *params);
180