1 /*	$NetBSD: dlz_minimal.h,v 1.5 2022/09/23 12:15:28 christos Exp $	*/
2 
3 /*
4  * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
5  *
6  * SPDX-License-Identifier: ISC
7  *
8  * Permission to use, copy, modify, and distribute this software for any purpose
9  * with or without fee is hereby granted, provided that the above copyright
10  * notice and this permission notice appear in all copies.
11  *
12  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
13  * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
14  * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
15  * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
16  * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
17  * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
18  * PERFORMANCE OF THIS SOFTWARE.
19  */
20 
21 /*
22  * This header provides a minimal set of defines and typedefs needed
23  * for building an external DLZ module for bind9. When creating a new
24  * external DLZ driver, please copy this header into your own source
25  * tree.
26  */
27 
28 #ifndef DLZ_MINIMAL_H
29 #define DLZ_MINIMAL_H 1
30 
31 #include <inttypes.h>
32 #include <stdbool.h>
33 #include <stdlib.h>
34 
35 #include <sys/socket.h>
36 #include <sys/types.h>
37 #ifdef ISC_PLATFORM_HAVESYSUNH
38 #include <sys/un.h>
39 #endif /* ifdef ISC_PLATFORM_HAVESYSUNH */
40 #include <arpa/inet.h>
41 #include <net/if.h>
42 #include <netinet/in.h>
43 
44 typedef unsigned int isc_result_t;
45 typedef uint32_t     dns_ttl_t;
46 
47 /*
48  * Define DLZ_DLOPEN_VERSION to different values to use older versions
49  * of the interface
50  */
51 #ifndef DLZ_DLOPEN_VERSION
52 #define DLZ_DLOPEN_VERSION 3
53 #define DLZ_DLOPEN_AGE	   0
54 #endif /* ifndef DLZ_DLOPEN_VERSION */
55 
56 /* return these in flags from dlz_version() */
57 #define DNS_SDLZFLAG_THREADSAFE	   0x00000001U
58 #define DNS_SDLZFLAG_RELATIVEOWNER 0x00000002U
59 #define DNS_SDLZFLAG_RELATIVERDATA 0x00000004U
60 
61 /* result codes */
62 #define ISC_R_SUCCESS	     0
63 #define ISC_R_NOMEMORY	     1
64 #define ISC_R_NOPERM	     6
65 #define ISC_R_NOSPACE	     19
66 #define ISC_R_NOTFOUND	     23
67 #define ISC_R_FAILURE	     25
68 #define ISC_R_NOTIMPLEMENTED 27
69 #define ISC_R_NOMORE	     29
70 #define ISC_R_INVALIDFILE    30
71 #define ISC_R_UNEXPECTED     34
72 #define ISC_R_FILENOTFOUND   38
73 
74 /* log levels */
75 #define ISC_LOG_INFO	     (-1)
76 #define ISC_LOG_NOTICE	     (-2)
77 #define ISC_LOG_WARNING	     (-3)
78 #define ISC_LOG_ERROR	     (-4)
79 #define ISC_LOG_CRITICAL     (-5)
80 #define ISC_LOG_DEBUG(level) (level)
81 
82 /* other useful definitions */
83 #define UNUSED(x) (void)(x)
84 #define DE_CONST(konst, var)           \
85 	do {                           \
86 		union {                \
87 			const void *k; \
88 			void	   *v; \
89 		} _u;                  \
90 		_u.k = konst;          \
91 		var = _u.v;            \
92 	} while (0)
93 
94 #if !defined(__has_attribute)
95 #define __has_attribute(x) 0
96 #endif /* if !defined(__has_attribute) */
97 
98 #if __GNUC__ >= 7 || __has_attribute(fallthrough)
99 #define FALLTHROUGH __attribute__((fallthrough))
100 #else
101 /* clang-format off */
102 #define FALLTHROUGH do {} while (0) /* FALLTHROUGH */
103 /* clang-format on */
104 #endif
105 
106 #ifdef __GNUC__
107 #define UNREACHABLE() __builtin_unreachable()
108 #else
109 #define UNREACHABLE() abort()
110 #endif
111 
112 /* opaque structures */
113 typedef void *dns_sdlzlookup_t;
114 typedef void *dns_sdlzallnodes_t;
115 typedef void *dns_view_t;
116 typedef void *dns_dlzdb_t;
117 
118 #if DLZ_DLOPEN_VERSION > 1
119 /*
120  * Method and type definitions needed for retrieval of client info
121  * from the caller.
122  */
123 typedef struct isc_sockaddr {
124 	union {
125 		struct sockaddr	    sa;
126 		struct sockaddr_in  sin;
127 		struct sockaddr_in6 sin6;
128 #ifdef ISC_PLATFORM_HAVESYSUNH
129 		struct sockaddr_un sunix;
130 #endif /* ifdef ISC_PLATFORM_HAVESYSUNH */
131 	} type;
132 	unsigned int length;
133 	void	    *link;
134 } isc_sockaddr_t;
135 
136 typedef struct isc_netaddr {
137 	unsigned int family;
138 	union {
139 		struct in_addr	in;
140 		struct in6_addr in6;
141 #ifdef ISC_PLATFORM_HAVESYSUNH
142 		char un[sizeof(((struct sockaddr_un *)0)->sun_path)];
143 #endif /* ifdef ISC_PLATFORM_HAVESYSUNH */
144 	} type;
145 	uint32_t zone;
146 } isc_netaddr_t;
147 
148 typedef struct dns_ecs {
149 	isc_netaddr_t addr;
150 	uint8_t	      source;
151 	uint8_t	      scope;
152 } dns_ecs_t;
153 
154 #define DNS_CLIENTINFO_VERSION 3
155 typedef struct dns_clientinfo {
156 	uint16_t  version;
157 	void	 *data;
158 	void	 *dbversion;
159 	dns_ecs_t ecs;
160 } dns_clientinfo_t;
161 
162 typedef isc_result_t (*dns_clientinfo_sourceip_t)(dns_clientinfo_t *client,
163 						  isc_sockaddr_t  **addrp);
164 
165 typedef isc_result_t (*dns_clientinfo_version_t)(dns_clientinfo_t *client,
166 						 void		 **addrp);
167 
168 #define DNS_CLIENTINFOMETHODS_VERSION 2
169 #define DNS_CLIENTINFOMETHODS_AGE     1
170 typedef struct dns_clientinfomethods {
171 	uint16_t		  version;
172 	uint16_t		  age;
173 	dns_clientinfo_sourceip_t sourceip;
174 } dns_clientinfomethods_t;
175 #endif /* DLZ_DLOPEN_VERSION > 1 */
176 
177 #define DNS_ECS_FORMATSIZE                                                \
178 	sizeof("xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:XXX.XXX.XXX.XXX%SSSSSSSSSS" \
179 	       "/NNN/NNN")
180 
181 /*
182  * Method definitions for callbacks provided by the dlopen driver
183  */
184 typedef void
185 log_t(int level, const char *fmt, ...);
186 
187 typedef isc_result_t
188 dns_sdlz_putrr_t(dns_sdlzlookup_t *lookup, const char *type, dns_ttl_t ttl,
189 		 const char *data);
190 
191 typedef isc_result_t
192 dns_sdlz_putnamedrr_t(dns_sdlzallnodes_t *allnodes, const char *name,
193 		      const char *type, dns_ttl_t ttl, const char *data);
194 
195 #if DLZ_DLOPEN_VERSION < 3
196 typedef isc_result_t
197 dns_dlz_writeablezone_t(dns_view_t *view, const char *zone_name);
198 #else  /* DLZ_DLOPEN_VERSION >= 3 */
199 typedef isc_result_t
200 dns_dlz_writeablezone_t(dns_view_t *view, dns_dlzdb_t *dlzdb,
201 			const char *zone_name);
202 #endif /* DLZ_DLOPEN_VERSION */
203 
204 /*
205  * prototypes for the functions you can include in your module
206  */
207 
208 /*
209  * dlz_version() is required for all DLZ external drivers. It should
210  * return DLZ_DLOPEN_VERSION.  'flags' is updated to indicate capabilities
211  * of the module.  In particular, if the module is thread-safe then it
212  * sets 'flags' to include DNS_SDLZFLAG_THREADSAFE.  Other capability
213  * flags may be added in the future.
214  */
215 int
216 dlz_version(unsigned int *flags);
217 
218 /*
219  * dlz_create() is required for all DLZ external drivers.
220  */
221 isc_result_t
222 dlz_create(const char *dlzname, unsigned int argc, char *argv[], void **dbdata,
223 	   ...);
224 
225 /*
226  * dlz_destroy() is optional, and will be called when the driver is
227  * unloaded if supplied
228  */
229 void
230 dlz_destroy(void *dbdata);
231 
232 /*
233  * dlz_findzonedb is required for all DLZ external drivers
234  */
235 #if DLZ_DLOPEN_VERSION < 3
236 isc_result_t
237 dlz_findzonedb(void *dbdata, const char *name);
238 #else  /* DLZ_DLOPEN_VERSION >= 3 */
239 isc_result_t
240 dlz_findzonedb(void *dbdata, const char *name, dns_clientinfomethods_t *methods,
241 	       dns_clientinfo_t *clientinfo);
242 #endif /* DLZ_DLOPEN_VERSION */
243 
244 /*
245  * dlz_lookup is required for all DLZ external drivers
246  */
247 #if DLZ_DLOPEN_VERSION == 1
248 isc_result_t
249 dlz_lookup(const char *zone, const char *name, void *dbdata,
250 	   dns_sdlzlookup_t *lookup);
251 #else  /* DLZ_DLOPEN_VERSION > 1 */
252 isc_result_t
253 dlz_lookup(const char *zone, const char *name, void *dbdata,
254 	   dns_sdlzlookup_t *lookup, dns_clientinfomethods_t *methods,
255 	   dns_clientinfo_t *clientinfo);
256 #endif /* DLZ_DLOPEN_VERSION */
257 
258 /*
259  * dlz_authority() is optional if dlz_lookup() supplies
260  * authority information (i.e., SOA, NS) for the dns record
261  */
262 isc_result_t
263 dlz_authority(const char *zone, void *dbdata, dns_sdlzlookup_t *lookup);
264 
265 /*
266  * dlz_allowzonexfr() is optional, and should be supplied if you want to
267  * support zone transfers
268  */
269 isc_result_t
270 dlz_allowzonexfr(void *dbdata, const char *name, const char *client);
271 
272 /*
273  * dlz_allnodes() is optional, but must be supplied if supply a
274  * dlz_allowzonexfr() function
275  */
276 isc_result_t
277 dlz_allnodes(const char *zone, void *dbdata, dns_sdlzallnodes_t *allnodes);
278 
279 /*
280  * dlz_newversion() is optional. It should be supplied if you want to
281  * support dynamic updates.
282  */
283 isc_result_t
284 dlz_newversion(const char *zone, void *dbdata, void **versionp);
285 
286 /*
287  * dlz_closeversion() is optional, but must be supplied if you supply a
288  * dlz_newversion() function
289  */
290 void
291 dlz_closeversion(const char *zone, bool commit, void *dbdata, void **versionp);
292 
293 /*
294  * dlz_configure() is optional, but must be supplied if you want to support
295  * dynamic updates
296  */
297 #if DLZ_DLOPEN_VERSION < 3
298 isc_result_t
299 dlz_configure(dns_view_t *view, void *dbdata);
300 #else  /* DLZ_DLOPEN_VERSION >= 3 */
301 isc_result_t
302 dlz_configure(dns_view_t *view, dns_dlzdb_t *dlzdb, void *dbdata);
303 #endif /* DLZ_DLOPEN_VERSION */
304 
305 /*
306  * dlz_ssumatch() is optional, but must be supplied if you want to support
307  * dynamic updates
308  */
309 bool
310 dlz_ssumatch(const char *signer, const char *name, const char *tcpaddr,
311 	     const char *type, const char *key, uint32_t keydatalen,
312 	     uint8_t *keydata, void *dbdata);
313 
314 /*
315  * dlz_addrdataset() is optional, but must be supplied if you want to
316  * support dynamic updates
317  */
318 isc_result_t
319 dlz_addrdataset(const char *name, const char *rdatastr, void *dbdata,
320 		void *version);
321 
322 /*
323  * dlz_subrdataset() is optional, but must be supplied if you want to
324  * support dynamic updates
325  */
326 isc_result_t
327 dlz_subrdataset(const char *name, const char *rdatastr, void *dbdata,
328 		void *version);
329 
330 /*
331  * dlz_delrdataset() is optional, but must be supplied if you want to
332  * support dynamic updates
333  */
334 isc_result_t
335 dlz_delrdataset(const char *name, const char *type, void *dbdata,
336 		void *version);
337 
338 #endif /* DLZ_MINIMAL_H */
339