1 /**************************************************************************************************
2 	$Id: mydns.h,v 1.98 2005/12/18 19:16:41 bboy Exp $
3 
4 	libmydns.h: Header file for the MyDNS library.
5 
6 	Copyright (C) 2002-2005  Don Moore <bboy@bboy.net>
7 
8 	This program is free software; you can redistribute it and/or modify
9 	it under the terms of the GNU General Public License as published by
10 	the Free Software Foundation; either version 2 of the License, or
11 	(at Your option) any later version.
12 
13 	This program is distributed in the hope that it will be useful,
14 	but WITHOUT ANY WARRANTY; without even the implied warranty of
15 	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 	GNU General Public License for more details.
17 
18 	You should have received a copy of the GNU General Public License
19 	along with this program; if not, write to the Free Software
20 	Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
21 **************************************************************************************************/
22 
23 #ifndef _MYDNS_H
24 #define _MYDNS_H
25 
26 #include "mydnsutil.h"
27 #include "bits.h"
28 #include "header.h"
29 
30 /* Table names */
31 #define	MYDNS_SOA_TABLE	"soa"
32 #define	MYDNS_RR_TABLE		"rr"
33 
34 extern int		opt_daemon;
35 extern const char	*opt_conf;
36 extern uid_t		perms_uid;
37 extern gid_t		perms_gid;
38 
39 extern time_t		task_timeout;			/* Task timeout */
40 
41 extern int		axfr_enabled;			/* Allow AXFR? */
42 extern int		tcp_enabled;			/* Enable TCP? */
43 extern int		dns_update_enabled;		/* Enable DNS UPDATE? */
44 extern int		dns_notify_enabled;		/* Enable DNS NOTIFY? */
45 extern int		notify_timeout;
46 extern int		notify_retries;
47 extern const char	*notify_algorithm;
48 
49 extern int		dns_ixfr_enabled;		/* Enable IXFR functionality */
50 extern int		ixfr_gc_enabled;		/* Enable IXFR GC Processing */
51 extern uint32_t		ixfr_gc_interval;		/* Run the IXFR GC this often */
52 extern uint32_t		ixfr_gc_delay;			/* Delay before running first IXFR GC */
53 extern int		ignore_minimum;			/* Ignore minimum TTL? */
54 extern char		hostname[256];			/* This machine's hostname */
55 
56 extern int		wildcard_recursion;		/* Number of levels of ancestor to search for wildcards */
57 
58 extern const char	*mydns_dbengine;		/* The db engine to use when creating tables - MySQL only */
59 
60 extern uint32_t 	answer_then_quit;		/* Answer this many queries then quit */
61 extern int		show_data_errors;		/* Output data errors? */
62 
63 extern int		forward_recursive;		/* Forward recursive queries? */
64 extern int		recursion_timeout;
65 extern int		recursion_connect_timeout;
66 extern int		recursion_retries;
67 extern const char	*recursion_algorithm;
68 extern char		*recursive_fwd_server;		/* Name of server for recursive forwarding */
69 extern int		recursive_family;		/* Protocol family for recursion */
70 
71 #if DEBUG_ENABLED
72 extern int		debug_enabled;
73 
74 extern int		debug_all;
75 
76 extern int		debug_alias;
77 extern int		debug_array;
78 extern int		debug_axfr;
79 extern int		debug_cache;
80 extern int		debug_conf;
81 extern int		debug_data;
82 extern int		debug_db;
83 extern int		debug_encode;
84 extern int		debug_error;
85 extern int		debug_ixfr;
86 extern int		debug_ixfr_sql;
87 extern int		debug_lib_rr;
88 extern int		debug_lib_soa;
89 extern int		debug_listen;
90 extern int		debug_memman;
91 extern int		debug_notify;
92 extern int		debug_notify_sql;
93 extern int		debug_queue;
94 extern int		debug_recursive;
95 extern int		debug_reply;
96 extern int		debug_resolve;
97 extern int		debug_rr;
98 extern int		debug_servercomms;
99 extern int		debug_sort;
100 extern int		debug_sql;
101 extern int		debug_sql_queries;
102 extern int		debug_status;
103 extern int		debug_task;
104 extern int		debug_tcp;
105 extern int		debug_udp;
106 extern int		debug_update;
107 extern int		debug_update_sql;
108 #endif
109 
110 #if HAVE_IPV6
111 extern struct sockaddr_in6	recursive_sa6;	/* Recursive server (IPv6) */
112 #endif
113 extern struct sockaddr_in	recursive_sa;	/* Recursive server (IPv4) */
114 
115 /* Configurable table names */
116 extern char *mydns_soa_table_name;
117 extern char *mydns_rr_table_name;
118 
119 /* Configurable WHERE clauses */
120 extern char *mydns_soa_where_clause;
121 extern char *mydns_rr_where_clause;
122 
123 extern size_t mydns_rr_data_length;
124 
125 /* If this is nonzero, an 'active' field is assumed to exist in the table, and
126 	only active rows will be loaded by mydns_*_load() */
127 extern int mydns_soa_use_active;
128 #define mydns_set_soa_use_active(S)	\
129   (mydns_soa_use_active = (sql_iscolumn((S), mydns_soa_table_name, "active") && mydns_soa_use_active))
130 extern int mydns_rr_use_active;
131 #define mydns_set_rr_use_active(S)	\
132   (mydns_rr_use_active = (sql_iscolumn((S), mydns_rr_table_name, "active") && mydns_rr_use_active))
133 
134 extern int mydns_rr_extended_data;
135 #define mydns_set_rr_extended_data(S)   \
136   (mydns_rr_extended_data = sql_iscolumn((S), mydns_rr_table_name, "edata"))
137 
138 /* This is set by mydns_set_soa_use_xfer */
139 extern int mydns_soa_use_xfer;
140 #define mydns_set_soa_use_xfer(S)	\
141   (mydns_soa_use_xfer = (sql_iscolumn((S), mydns_soa_table_name, "xfer") && axfr_enabled))
142 
143 /* This is set by mydns_set_soa_use_update_acl */
144 extern int mydns_soa_use_update_acl;
145 #define mydns_set_soa_use_update_acl(S)	\
146   (mydns_soa_use_update_acl = (sql_iscolumn((S), mydns_soa_table_name, "update_acl") && dns_update_enabled))
147 
148 
149 extern int mydns_soa_use_recursive;
150 #define mydns_set_soa_use_recursive(S) \
151   (mydns_soa_use_recursive = (sql_iscolumn((S), mydns_soa_table_name, "recursive") && forward_recursive))
152 
153 extern char *mydns_soa_active_types[];
154 extern char *mydns_rr_active_types[];
155 
156 /* These are set for IXFR support */
157 extern int mydns_rr_use_stamp;
158 #define mydns_set_rr_use_stamp(S)	\
159   (mydns_rr_use_stamp = (sql_iscolumn((S), mydns_rr_table_name, "stamp") && dns_ixfr_enabled))
160 
161 extern int mydns_rr_use_serial;
162 #define mydns_set_rr_use_serial(S)	\
163   (mydns_rr_use_serial = (sql_iscolumn((S), mydns_rr_table_name, "serial") && dns_ixfr_enabled))
164 
165 /* NOTE: `type' is listed at the end so that we can possibly set the value of `aux' for
166 	convenience based on the RR type; for example, an `A' record might store the IP in `aux'. */
167 #define	MYDNS_SOA_NUMFIELDS	10
168 #ifdef DN_COLUMN_NAMES
169 #	define	MYDNS_SOA_FIELDS	"zone_id,CONCAT(origin,\".\"),\"ns\",CONCAT(owner,\".\"),serial,refresh,retry,expire,min_ttl,min_ttl"
170 #else
171 #	define	MYDNS_SOA_FIELDS	"id,origin,ns,mbox,serial,refresh,retry,expire,minimum,ttl"
172 #endif
173 
174 #define	MYDNS_RR_NUMFIELDS	7
175 #ifdef DN_COLUMN_NAMES
176 #	define	MYDNS_RR_FIELDS	"rr_id,zone_id,name,data,pref,7200,type"
177 #else
178 #	define	MYDNS_RR_FIELDS	"id,zone,name,data,aux,ttl,type"
179 #endif
180 
181 /* Does the specified string end with a dot? */
182 #define	ENDS_WITH_DOT(s)	(s && (s[strlen(s)-1] == '.'))
183 
184 /* Size ranges for various bits of DNS data */
185 #define	DNS_MAXPACKETLEN_TCP		65536		/* Use 64k for TCP */
186 #define	DNS_MAXPACKETLEN_UDP		512		/* RFC1035: "512 octets or less" */
187 #define	DNS_MAXNAMELEN			255		/* RFC1035: "255 octets or less" */
188 #define	DNS_MAXESC			DNS_MAXNAMELEN + DNS_MAXNAMELEN + 1
189 #define	DNS_MAXLABELLEN			63		/* RFC1035: "63 octets or less" */
190 #define	DNS_POINTER_MASK		0xC0
191 #define	DNS_QUERYBUFSIZ			512		/* Used as buffer size for SQL queries */
192 #define DNS_MAXDATALEN			65536		/* Should be RFC1035: Drawn from BIND LENGTHs
193 							 */
194 #define DNS_DATALEN			128		/* Length of data field */
195 #define DNS_MAXTXTLEN			2048		/* Arbitrary limit for TXT data */
196 #define DNS_MAXTXTELEMLEN		255		/* Maximum string length in a text entry */
197 /* Default values in SOA records */
198 #define	DNS_DEFAULT_REFRESH		28800
199 #define	DNS_DEFAULT_RETRY		7200
200 #define	DNS_DEFAULT_EXPIRE		604800
201 #define	DNS_DEFAULT_MINIMUM		86400
202 #define	DNS_DEFAULT_TTL			86400
203 #define	DNS_MINIMUM_TTL			300
204 
205 /* Information about the PTR suffix */
206 /* #define	PTR_SUFFIX					".in-addr.arpa." */
207 /* #define	PTR_SUFFIX_LEN				14 */
208 
209 /* Macro to convert quads into address -- result like MySQL's INET_ATON() */
210 #define INET_ATON(a,b,c,d) (((a) << 24) | ((b) << 16) | ((c) << 8) | (d))
211 
212 
213 typedef enum _task_error_t					/* Common errors */
214 {
215 	ERR_NONE = 0,						/* No error */
216 	ERR_INTERNAL,						/* "Internal error" */
217 	ERR_ZONE_NOT_FOUND,					/* "Zone not found" */
218 	ERR_NO_MATCHING_RECORDS,				/* "No matching resource records" */
219 	ERR_NO_AXFR,						/* "AXFR disabled" */
220 	ERR_RR_NAME_TOO_LONG,					/* "Name too long in RR" */
221 	ERR_RR_LABEL_TOO_LONG,					/* "Label too long in RR" */
222 	ERR_Q_BUFFER_OVERFLOW,					/* "Input name buffer overflow" */
223 	ERR_Q_INVALID_COMPRESSION,				/* "Invalid compression method" */
224 	ERR_Q_NAME_TOO_LONG,					/* "Question name too long" */
225 	ERR_Q_LABEL_TOO_LONG,					/* "Question label too long" */
226 	ERR_NO_CLASS,						/* "Unknown class" */
227 	ERR_NAME_FORMAT,					/* "Invalid name format" */
228 	ERR_TIMEOUT,						/* "Communications timeout" */
229 	ERR_BROKEN_GLUE,					/* "Malformed glue" */
230 	ERR_INVALID_ADDRESS,					/* "Invalid address" */
231 	ERR_INVALID_TYPE,					/* "Invalid type" */
232 	ERR_INVALID_CLASS,					/* "Invalid class" */
233 	ERR_INVALID_TTL,					/* "Invalid TTL" (for update) */
234 	ERR_INVALID_DATA,					/* "Invalid data" (for update) */
235 	ERR_DB_ERROR,						/* "Database error" */
236 	ERR_NO_QUESTION,					/* "No question in query" */
237 	ERR_NO_AUTHORITY,					/* "No authority data" (for ixfr) */
238 	ERR_MULTI_QUESTIONS,					/* "Multiple questions in query" */
239 	ERR_MULTI_AUTHORITY,					/* "Multiple authority records in quer" */
240 	ERR_QUESTION_TRUNCATED,					/* "Question truncated" */
241 	ERR_UNSUPPORTED_OPCODE,					/* "Unsupported opcode" */
242 	ERR_UNSUPPORTED_TYPE,					/* "Unsupported type" */
243 	ERR_MALFORMED_REQUEST,					/* "Malformed request" */
244 	ERR_IXFR_NOT_ENABLED,					/* "IXFR not enabled" */
245 	ERR_TCP_NOT_ENABLED,					/* "TCP not enabled" */
246 	ERR_RESPONSE_BIT_SET,					/* "Response bit set on query" */
247 	ERR_FWD_RECURSIVE,					/* "Recursive query forwarding error" */
248 	ERR_NO_UPDATE,						/* "UPDATE denied" */
249 	ERR_PREREQUISITE_FAILED,				/* "UPDATE prerequisite failed" */
250 
251 } task_error_t;
252 
253 
254 typedef enum							/* Query classes */
255 {
256 	DNS_CLASS_UNKNOWN 	= -1,				/* Unknown */
257 
258 	DNS_CLASS_IN		= 1,				/* Internet */
259 	DNS_CLASS_CHAOS		= 3,				/* CHAOS (obsolete) */
260 	DNS_CLASS_HESIOD	= 4,				/* HESIOD (obsolete) */
261 
262 	DNS_CLASS_NONE		= 254,				/* NONE (RFC 2136) */
263 	DNS_CLASS_ANY		= 255				/* ANY */
264 
265 } dns_class_t;
266 
267 
268 typedef enum							/* Query types */
269 {
270 	DNS_QTYPE_UNKNOWN		= -1,			/* Unknown */
271 
272 	DNS_QTYPE_NONE			= 0,			/* None/invalid */
273 	DNS_QTYPE_A			= 1,			/* Address */
274 	DNS_QTYPE_NS			= 2,			/* Nameserver */
275 	DNS_QTYPE_MD			= 3,			/* Mail dest */
276 	DNS_QTYPE_MF			= 4,			/* Mail forwarder */
277 	DNS_QTYPE_CNAME			= 5,			/* Canonical name */
278 	DNS_QTYPE_SOA			= 6,			/* Start of authority */
279 	DNS_QTYPE_MB			= 7,			/* Mailbox name */
280 	DNS_QTYPE_MG			= 8,			/* Mail group */
281 	DNS_QTYPE_MR			= 9,			/* Mail rename */
282 	DNS_QTYPE_NULL			= 10,			/* Null */
283 	DNS_QTYPE_WKS			= 11,			/* Well known service */
284 	DNS_QTYPE_PTR			= 12,			/* IP -> fqdn mapping */
285 	DNS_QTYPE_HINFO			= 13,			/* Host info */
286 	DNS_QTYPE_MINFO			= 14,			/* Mailbox info */
287 	DNS_QTYPE_MX			= 15,			/* Mail routing info */
288 	DNS_QTYPE_TXT			= 16,			/* Text */
289 	DNS_QTYPE_RP			= 17,			/* Responsible person */
290 	DNS_QTYPE_AFSDB			= 18,			/* AFS cell database */
291 	DNS_QTYPE_X25			= 19,			/* X_25 calling address */
292 	DNS_QTYPE_ISDN			= 20,			/* ISDN calling address */
293 	DNS_QTYPE_RT			= 21,			/* Router */
294 	DNS_QTYPE_NSAP			= 22,			/* NSAP address */
295 	DNS_QTYPE_NSAP_PTR		= 23,			/* Reverse NSAP lookup (depreciated) */
296 	DNS_QTYPE_SIG			= 24,			/* Security signature */
297 	DNS_QTYPE_KEY			= 25,			/* Security key */
298 	DNS_QTYPE_PX			= 26,			/* X.400 mail mapping */
299 	DNS_QTYPE_GPOS			= 27,			/* Geographical position (withdrawn) */
300 	DNS_QTYPE_AAAA			= 28,			/* IPv6 Address */
301 	DNS_QTYPE_LOC			= 29,			/* Location info */
302 	DNS_QTYPE_NXT			= 30,			/* Next domain (security) */
303 	DNS_QTYPE_EID			= 31,			/* Endpoint identifier */
304 	DNS_QTYPE_NIMLOC		= 32,			/* Nimrod Locator */
305 	DNS_QTYPE_SRV			= 33,			/* Server */
306 	DNS_QTYPE_ATMA			= 34,			/* ATM Address */
307 	DNS_QTYPE_NAPTR			= 35,			/* Naming Authority Pointer */
308 	DNS_QTYPE_KX			= 36,			/* Key Exchange */
309 	DNS_QTYPE_CERT			= 37,			/* Certification record */
310 	DNS_QTYPE_A6			= 38,			/* IPv6 address (deprecates AAAA) */
311 	DNS_QTYPE_DNAME			= 39,			/* Non-terminal DNAME (for IPv6) */
312 	DNS_QTYPE_SINK			= 40,			/* Kitchen sink (experimentatl) */
313 	DNS_QTYPE_OPT			= 41,			/* EDNS0 option (meta-RR) */
314 	DNS_QTYPE_APL			= 42,
315 	DNS_QTYPE_DS			= 43,
316 	DNS_QTYPE_SSHFP			= 44,
317 	DNS_QTYPE_IPSECKEY		= 45,
318 	DNS_QTYPE_RRSIG			= 46,
319 	DNS_QTYPE_NSEC			= 47,
320 	DNS_QTYPE_DNSKEY		= 48,
321 	DNS_QTYPE_DHCID			= 49,
322 	DNS_QTYPE_NSEC3			= 50,
323 	DNS_QTYPE_NSEC3PARAM		= 51,
324 
325 	DNS_QTYPE_HIP			= 55,
326 
327 	DNS_QTYPE_SPF			= 99,
328 	DNS_QTYPE_UINFO			= 100,
329 	DNS_QTYPE_UID			= 101,
330 	DNS_QTYPE_GID			= 102,
331 	DNS_QTYPE_UNSPEC		= 103,
332 
333 	DNS_QTYPE_TKEY			= 249,
334 	DNS_QTYPE_TSIG			= 250,			/* Transaction signature */
335 	DNS_QTYPE_IXFR			= 251,			/* Incremental zone transfer */
336 	DNS_QTYPE_AXFR			= 252,			/* Zone transfer */
337 	DNS_QTYPE_MAILB			= 253,			/* Transfer mailbox records */
338 	DNS_QTYPE_MAILA			= 254,			/* Transfer mail agent records */
339 	DNS_QTYPE_ANY			= 255,			/* Any */
340 
341 	DNS_QTYPE_TA			= 32768,
342 	DNS_QTYPE_DLV			= 32769,
343 
344 #if ALIAS_ENABLED
345 	DNS_QTYPE_ALIAS			= 65280,		/* Extension - David Phillips, alias patch */
346 #endif
347 } dns_qtype_t;
348 
349 
350 typedef enum							/* DNS opcode types */
351 {
352 	DNS_OPCODE_UNKNOWN		= -1,			/* Unknown */
353 
354 	DNS_OPCODE_QUERY		= 0,			/* Query (RFC 1035) */
355 	DNS_OPCODE_IQUERY		= 1,			/* Inverse query (RFC 1035) */
356 	DNS_OPCODE_STATUS		= 2,			/* Status request (RFC 1035) */
357 
358 	DNS_OPCODE_NOTIFY		= 4,			/* Notify request (RFC 1996) */
359 	DNS_OPCODE_UPDATE		= 5,			/* Update request (RFC 2136) */
360 } dns_opcode_t;
361 
362 
363 
364 
365 /* Return codes */
366 typedef enum
367 {
368 	DNS_RCODE_UNKNOWN		= -1,		/* Unknown */
369 
370 	DNS_RCODE_NOERROR		= 0,		/* No error (RFC 1035) */
371 	DNS_RCODE_FORMERR		= 1,		/* Format error (RFC 1035) */
372 	DNS_RCODE_SERVFAIL		= 2,		/* Server failure (RFC 1035) */
373 	DNS_RCODE_NXDOMAIN		= 3,		/* Nonexistent domain (RFC 1035) */
374 	DNS_RCODE_NOTIMP		= 4,		/* Not implemented (RFC 1035) */
375 	DNS_RCODE_REFUSED		= 5,		/* Query refused (RFC 1035) */
376 
377 	DNS_RCODE_YXDOMAIN		= 6,		/* Name exists when it should not (RFC 2136) */
378 	DNS_RCODE_YXRRSET		= 7,		/* RR set exists when it should not (RFC 2136) */
379 	DNS_RCODE_NXRRSET		= 8,		/* RR set that should exist does not (RFC 2136) */
380 	DNS_RCODE_NOTAUTH		= 9,		/* Server not authoritative for zone (RFC 2136) */
381 	DNS_RCODE_NOTZONE		= 10,		/* Name not contained in zone (RFC 2136) */
382 
383 	/* Codes that can't fit in 4 bits are found in OPT (RFC 2671), TSIG (RFC 2845), and
384 		TKEY (RFC 2930) RRs */
385 	/* RFC 2671 says that rcode 16 is BADVERS ("Bad OPT version").  This conlicts with
386 		RFC 2845.  RFC 2845 seems like best current practice. */
387 
388 	DNS_RCODE_BADVERS		= 16,		/* Bad OPT Version */
389 	DNS_RCODE_BADSIG		= 16,		/* TSIG signature failure (RFC 2845) */
390 	DNS_RCODE_BADKEY		= 17,		/* Key not recognized (RFC 2845) */
391 	DNS_RCODE_BADTIME		= 18,		/* Signature out of time window (RFC 2845) */
392 	DNS_RCODE_BADMODE		= 19,		/* Bad TKEY mode (RFC 2930) */
393 	DNS_RCODE_BADNAME		= 20,		/* Duplicate key name (RFC 2930) */
394 	DNS_RCODE_BADALG		= 21,		/* Algorithm not supported (RFC 2930) */
395 	DNS_RCODE_BADTRUNC		= 22,		/* Bad Truncation */
396 
397 } dns_rcode_t;
398 
399 
400 /* The record types */
401 typedef enum _dns_rrtype_t				/* DNS record types (for MyDNS) */
402 {
403 	DNS_RRTYPE_SOA,
404 	DNS_RRTYPE_RR
405 } dns_rrtype_t;
406 
407 
408 typedef enum _datasection_t				/* Sections in reply */
409 {
410 	QUESTION = 0,
411 	ANSWER,
412 	AUTHORITY,
413 	ADDITIONAL
414 } datasection_t;
415 
416 
417 /*
418 **  Structures describing each record type
419 */
420 typedef struct _mydns_soa				/* `soa' table data (zones of authority) */
421 {
422 	uint32_t		id;
423 	char			origin[DNS_MAXNAMELEN + 1];
424 	char			ns[DNS_MAXNAMELEN + 1];
425 	char			mbox[DNS_MAXNAMELEN + 1];
426 	uint32_t		serial;
427 	uint32_t		refresh;
428 	uint32_t		retry;
429 	uint32_t		expire;
430 	uint32_t		minimum;
431 	uint32_t		ttl;
432         /* This field is used to specify if the zone is to be auto-recursive */
433         uint32_t                recursive;
434 
435 	struct _mydns_soa *next;
436 } MYDNS_SOA;
437 
438 typedef struct _mydns_rr {				/* `rr' table data (resource records) */
439 
440   struct _mydns_rr	*next;
441   uint32_t		id;
442   uint32_t		zone;
443   dns_qtype_t		type;
444   dns_class_t		class;
445   uint32_t		aux;
446   uint32_t		ttl;
447 #if ALIAS_ENABLED
448   int			alias;
449 #endif
450 
451   char			*active;
452 #if USE_PGSQL
453   timestamp		*stamp;
454 #else
455   MYSQL_TIME		*stamp;
456 #endif
457   uint32_t		serial;
458 
459   char			*_name;		/* Max contents is DNS_MAXNAMELEN */
460   struct {
461     uint16_t		len;
462     void		*value;
463   }			_data;		/* Max contents is DNS_MAXDATALEN */
464 
465   union {
466     /* This data used by SRV records only - parsed (and removed) from "data" */
467     struct {
468       uint16_t		weight;
469       uint16_t		port;
470     } srv;
471 
472     /* For RP records, this points to the "txt" part of the data, which is preceded by a NUL */
473     char		*_rp_txt;	/* Max contents is DNS_MAXNAMELEN */
474 
475     /*
476     ** Data for NAPTR records:
477     **
478     ** This is potentially a lot of data.  I'm a little unclear from the RFC on what the
479     ** maximum length of some of these fields are, so I'm just making them big for now.
480     ** Hopefully these extra fields won't take up too much extra memory in the cache, slowing
481     ** down the mere mortals who don't use NAPTR
482     **
483     ** The replacement field could be aliased to the data structure above e.g. _data
484     ** but as this is a true NUL terminated string we zero out _data instead
485     */
486     struct {
487       uint16_t		order;
488       uint16_t		pref;
489       char		flags[8];	/* Stored in binary in the database ? */
490       char		*_service;	/* Max contents is DNS_MAXNAMELEN */
491       char		*_regex;	/* Max contents is DNS_MAXNAMELEN */
492       char		*_replacement;	/* Max contents is DNS_MAXNAMELEN */
493     } naptr;
494   } recData;
495 
496 } MYDNS_RR;
497 
498 #if DEBUG_ENABLED
499 extern void *__mydns_rr_assert_pointer(void *, const char *, const char *, int);
500 #define MYDNS_RR_NAME(__rrp)		  ((char*)__mydns_rr_assert_pointer((__rrp)->_name, \
501 									    "name", __FILE__, __LINE__))
502 #define MYDNS_RR_DATA_VALUE(__rrp)	  (__mydns_rr_assert_pointer((__rrp)->_data.value, \
503 								     "data.value", __FILE__, __LINE__))
504 #define MYDNS_RR_RP_TXT(__rrp)		  ((char*)__mydns_rr_assert_pointer((__rrp)->recData._rp_txt, \
505 									    "rp_txt", __FILE__, __LINE__))
506 #define MYDNS_RR_NAPTR_SERVICE(__rrp)	  ((char*)__mydns_rr_assert_pointer((__rrp)->recData.naptr._service, \
507 									    "naptr_service", __FILE__, __LINE__))
508 #define MYDNS_RR_NAPTR_REGEX(__rrp)	  ((char*)__mydns_rr_assert_pointer((__rrp)->recData.naptr._regex, \
509 									    "naptr_regex", __FILE__, __LINE__))
510 #define MYDNS_RR_NAPTR_REPLACEMENT(__rrp) ((char*)__mydns_rr_assert_pointer((__rrp)->recData.naptr._replacement, \
511 									   "naptr_replacement", \
512 									   __FILE__, __LINE__))
513 #else
514 #define MYDNS_RR_NAME(__rrp)			((__rrp)->_name)
515 #define MYDNS_RR_DATA_VALUE(__rrp)		((__rrp)->_data.value)
516 #define MYDNS_RR_RP_TXT(__rrp)			((__rrp)->recData._rp_txt)
517 #define MYDNS_RR_NAPTR_SERVICE(__rrp)		((__rrp)->recData.naptr._service)
518 #define MYDNS_RR_NAPTR_REGEX(__rrp)		((__rrp)->recData.naptr._regex)
519 #define MYDNS_RR_NAPTR_REPLACEMENT(__rrp)	((__rrp)->recData.naptr._replacement)
520 #endif
521 
522 #define MYDNS_RR_DATA(__rrp)			MYDNS_RR_DATA_VALUE(__rrp)
523 #define MYDNS_RR_DATA_LENGTH(__rrp)		((__rrp)->_data.len)
524 #define MYDNS_RR_SRV_WEIGHT(__rrp)		((__rrp)->recData.srv.weight)
525 #define MYDNS_RR_SRV_PORT(__rrp)		((__rrp)->recData.srv.port)
526 #define MYDNS_RR_NAPTR_ORDER(__rrp)		((__rrp)->recData.naptr.order)
527 #define MYDNS_RR_NAPTR_PREF(__rrp)		((__rrp)->recData.naptr.pref)
528 #define MYDNS_RR_NAPTR_FLAGS(__rrp)		((__rrp)->recData.naptr.flags)
529 
530 /* sql.c */
531 #if USE_PGSQL
532 typedef PGconn SQL;
533 typedef unsigned char ** SQL_ROW;
534 typedef struct _sql_res {
535 	PGresult	*result;
536 	int		tuples;
537 	int		fields;
538 	int		current_tuple;
539 	SQL_ROW		current_row;
540   	unsigned long	*current_length;
541 } SQL_RES;
542 #else
543 typedef MYSQL SQL;
544 typedef MYSQL_RES SQL_RES;
545 typedef MYSQL_ROW SQL_ROW;
546 #endif
547 
548 
549 
550 /* ip.c */
551 extern uint32_t		mydns_revstr_ip4(const uchar *);
552 extern int		mydns_extract_arpa(const uchar *, uint8_t ip[]);
553 
554 
555 /* rr.c */
556 extern long		mydns_rr_count(SQL *);
557 extern void		mydns_rr_get_active_types(SQL *);
558 extern void		mydns_set_rr_table_name(const char *);
559 extern void		mydns_set_rr_where_clause(const char *);
560 extern dns_qtype_t	mydns_rr_get_type(char *);
561 extern char *		mydns_rr_append_origin(char *, char *);
562 extern void		mydns_rr_name_append_origin(MYDNS_RR *, char *);
563 extern void		mydns_rr_data_append_origin(MYDNS_RR *, char *);
564 extern void		_mydns_rr_free(MYDNS_RR *);
565 #define			mydns_rr_free(p)	if ((p)) _mydns_rr_free((p)), (p) = NULL
566 extern MYDNS_RR		*mydns_rr_build(uint32_t, uint32_t, dns_qtype_t, dns_class_t, uint32_t, uint32_t,
567 					char *active,
568 #if USE_PGSQL
569 					timestamp *stamp,
570 #else
571 					MYSQL_TIME *stamp,
572 #endif
573 					uint32_t, char *, char *,  uint16_t, const char *);
574 extern MYDNS_RR		*mydns_rr_parse(SQL_ROW, unsigned long *, const char *);
575 extern char		*mydns_rr_columns(void);
576 extern char		*mydns_rr_prepare_query(uint32_t, dns_qtype_t, const char *,
577 						const char *, const char *, const char *, const char *);
578 extern int		mydns_rr_load_all(SQL *, MYDNS_RR **, uint32_t, dns_qtype_t, const char *, const char *);
579 extern int		mydns_rr_load_active(SQL *, MYDNS_RR **, uint32_t, dns_qtype_t, const char *, const char *);
580 extern int		mydns_rr_load_inactive(SQL *, MYDNS_RR **, uint32_t, dns_qtype_t, const char *, const char *);
581 extern int		mydns_rr_load_deleted(SQL *, MYDNS_RR **, uint32_t, dns_qtype_t, const char *, const char *);
582 extern int		mydns_rr_count_all(SQL *, uint32_t, dns_qtype_t, const char *, const char *);
583 extern int		mydns_rr_count_active(SQL *, uint32_t, dns_qtype_t, const char *, const char *);
584 extern int		mydns_rr_count_inactive(SQL *, uint32_t, dns_qtype_t, const char *, const char *);
585 extern int		mydns_rr_count_deleted(SQL *, uint32_t, dns_qtype_t, const char *, const char *);
586 extern int		mydns_rr_load_all_filtered(SQL *, MYDNS_RR **, uint32_t, dns_qtype_t, const char *, const char *, const char *);
587 extern int		mydns_rr_load_active_filtered(SQL *, MYDNS_RR **, uint32_t, dns_qtype_t, const char *, const char *, const char *);
588 extern int		mydns_rr_load_inactive_filtered(SQL *, MYDNS_RR **, uint32_t, dns_qtype_t, const char *, const char *, const char *);
589 extern int		mydns_rr_load_deleted_filtered(SQL *, MYDNS_RR **, uint32_t, dns_qtype_t, const char *, const char *, const char *);
590 extern int		mydns_rr_count_all_filtered(SQL *, uint32_t, dns_qtype_t, const char *, const char *, const char *);
591 extern int		mydns_rr_count_active_filtered(SQL *, uint32_t, dns_qtype_t, const char *, const char *, const char *);
592 extern int		mydns_rr_count_inactive_filtered(SQL *, uint32_t, dns_qtype_t, const char *, const char *, const char *);
593 extern int		mydns_rr_count_deleted_filtered(SQL *, uint32_t, dns_qtype_t, const char *, const char *, const char *);
594 extern MYDNS_RR		*mydns_rr_dup(MYDNS_RR *, int);
595 extern size_t		mydns_rr_size(MYDNS_RR *);
596 
597 /* soa.c */
598 extern long		mydns_soa_count(SQL *);
599 extern void		mydns_soa_get_active_types(SQL *);
600 extern void		mydns_set_soa_table_name(const char *);
601 extern void		mydns_set_soa_where_clause(const char *);
602 extern int		mydns_soa_load(SQL *, MYDNS_SOA **, const char *);
603 extern int		mydns_soa_make(SQL *, MYDNS_SOA **, unsigned char *, unsigned char *);
604 extern MYDNS_SOA	*mydns_soa_dup(MYDNS_SOA *, int);
605 extern size_t		mydns_soa_size(MYDNS_SOA *);
606 extern void		_mydns_soa_free(MYDNS_SOA *);
607 #define			mydns_soa_free(p)	if ((p)) _mydns_soa_free((p)), (p) = NULL
608 
609 
610 /* sql.c */
611 extern SQL		*sql;
612 extern void		sql_open(const char *user, const char *password, const char *host, const char *database);
613 extern void		sql_reopen(void);
614 extern void		_sql_close(SQL *);
615 #define			sql_close(p) if ((p)) _sql_close((p)), (p) = NULL
616 extern int		sql_nrquery(SQL *, const char *query, size_t querylen);
617 extern SQL_RES		*sql_query(SQL *, const char *query, size_t querylen);
618 extern SQL_RES		*sql_queryf(SQL *, const char *, ...) __printflike(2,3);
619 extern long		sql_count(SQL *, const char *, ...) __printflike(2,3);
620 extern SQL_ROW		sql_getrow(SQL_RES *res, unsigned long **lengths);
621 extern char		*sql_escstr2(SQL *, char *, size_t);
622 extern char		*sql_escstr(SQL *, char *);
623 extern void		_sql_free(SQL_RES *res);
624 extern long		sql_num_rows(SQL_RES *res);
625 extern int		sql_istable(SQL *, const char *);
626 extern int		sql_iscolumn(SQL *, const char *, const char *);
627 extern int		sql_get_column_width(SQL *, const char *, const char *);
628 extern int		sql_build_query(char **, const char *, ...) __printflike(2,3);
629 #define			sql_free(p) if ((p)) _sql_free((p)), (p) = NULL
630 
631 
632 /* str.c */
633 extern const char	*mydns_qtype_str(dns_qtype_t);
634 extern const char	*mydns_class_str(dns_class_t);
635 extern const char	*mydns_opcode_str(dns_opcode_t);
636 extern const char	*mydns_rcode_str(dns_rcode_t);
637 extern const char	*mydns_section_str(datasection_t);
638 extern int		hinfo_parse(char *, char *, char *, size_t);
639 
640 
641 /* unencode.c */
642 extern uchar		*name_unencode(uchar *, size_t, uchar *, uchar *, size_t);
643 extern uchar		*name_unencode2(uchar *, size_t, uchar **, task_error_t *);
644 
645 /* conf.c */
646 extern void		load_config(void);
647 extern void		dump_config(void);
648 extern void		conf_set_logging(void);
649 extern void		check_config_file_perms(void);
650 
651 
652 /* db.c */
653 extern void		db_connect(void);
654 extern void		db_output_create_tables(void);
655 extern void		db_check_optional(void);
656 extern void		db_verify_tables(void);
657 
658 
659 #endif /* !_MYDNS_H */
660 
661 /* vi:set ts=3: */
662