xref: /openbsd-src/usr.sbin/nsd/util.h (revision f2da64fbbbf1b03f09f390ab01267c93dfd77c4c)
1 /*
2  * util.h -- set of various support routines.
3  *
4  * Copyright (c) 2001-2006, NLnet Labs. All rights reserved.
5  *
6  * See LICENSE for the license.
7  *
8  */
9 
10 #ifndef _UTIL_H_
11 #define _UTIL_H_
12 
13 #include <sys/time.h>
14 #include <stdarg.h>
15 #include <stdio.h>
16 #include <time.h>
17 struct rr;
18 struct buffer;
19 struct region;
20 
21 #ifdef HAVE_SYSLOG_H
22 #  include <syslog.h>
23 #else
24 #  define LOG_ERR 3
25 #  define LOG_WARNING 4
26 #  define LOG_NOTICE 5
27 #  define LOG_INFO 6
28 #endif
29 
30 #define ALIGN_UP(n, alignment)  \
31 	(((n) + (alignment) - 1) & (~((alignment) - 1)))
32 #define PADDING(n, alignment)   \
33 	(ALIGN_UP((n), (alignment)) - (n))
34 
35 /*
36  * Initialize the logging system.  All messages are logged to stderr
37  * until log_open and log_set_log_function are called.
38  */
39 void log_init(const char *ident);
40 
41 /*
42  * Open the system log.  If FILENAME is not NULL, a log file is opened
43  * as well.
44  */
45 void log_open(int option, int facility, const char *filename);
46 
47 /*
48  * Reopen the logfile.
49  */
50 void log_reopen(const char *filename, uint8_t verbose);
51 
52 /*
53  * Finalize the logging system.
54  */
55 void log_finalize(void);
56 
57 /*
58  * Type of function to use for the actual logging.
59  */
60 typedef void log_function_type(int priority, const char *message);
61 
62 /*
63  * The function used to log to the log file.
64  */
65 log_function_type log_file;
66 
67 /*
68  * The function used to log to syslog.  The messages are also logged
69  * using log_file.
70  */
71 log_function_type log_syslog;
72 
73 /*
74  * Set the logging function to use (log_file or log_syslog).
75  */
76 void log_set_log_function(log_function_type *log_function);
77 
78 /*
79  * Log a message using the current log function.
80  */
81 void log_msg(int priority, const char *format, ...)
82 	ATTR_FORMAT(printf, 2, 3);
83 
84 /*
85  * Log a message using the current log function.
86  */
87 void log_vmsg(int priority, const char *format, va_list args);
88 
89 /*
90  * Verbose output switch
91  */
92 extern int verbosity;
93 #define VERBOSITY(level, args)					\
94 	do {							\
95 		if ((level) <= verbosity) {			\
96 			log_msg args ;				\
97 		}						\
98 	} while (0)
99 
100 /*
101  * Set the INDEXth bit of BITS to 1.
102  */
103 void set_bit(uint8_t bits[], size_t index);
104 
105 /*
106  * Set the INDEXth bit of BITS to 0.
107  */
108 void clear_bit(uint8_t bits[], size_t index);
109 
110 /*
111  * Return the value of the INDEXth bit of BITS.
112  */
113 int get_bit(uint8_t bits[], size_t index);
114 
115 /* A general purpose lookup table */
116 typedef struct lookup_table lookup_table_type;
117 struct lookup_table {
118 	int id;
119 	const char *name;
120 };
121 
122 /*
123  * Looks up the table entry by name, returns NULL if not found.
124  */
125 lookup_table_type *lookup_by_name(lookup_table_type table[], const char *name);
126 
127 /*
128  * Looks up the table entry by id, returns NULL if not found.
129  */
130 lookup_table_type *lookup_by_id(lookup_table_type table[], int id);
131 
132 /*
133  * (Re-)allocate SIZE bytes of memory.  Report an error if the memory
134  * could not be allocated and exit the program.  These functions never
135  * return NULL.
136  */
137 void *xalloc(size_t size);
138 void *xmallocarray(size_t num, size_t size);
139 void *xalloc_zero(size_t size);
140 void *xalloc_array_zero(size_t num, size_t size);
141 void *xrealloc(void *ptr, size_t size);
142 
143 /*
144  * Mmap allocator routines.
145  *
146  */
147 #ifdef USE_MMAP_ALLOC
148 void *mmap_alloc(size_t size);
149 void mmap_free(void *ptr);
150 #endif /* USE_MMAP_ALLOC */
151 
152 /*
153  * Write SIZE bytes of DATA to FILE.  Report an error on failure.
154  *
155  * Returns 0 on failure, 1 on success.
156  */
157 int write_data(FILE *file, const void *data, size_t size);
158 
159 /*
160  * like write_data, but keeps track of crc
161  */
162 int write_data_crc(FILE *file, const void *data, size_t size, uint32_t* crc);
163 
164 /*
165  * Write the complete buffer to the socket, irrespective of short
166  * writes or interrupts. This function blocks to write the data.
167  * Returns 0 on error, 1 on success.
168  */
169 int write_socket(int s, const void *data, size_t size);
170 
171 /*
172  * Copy data allowing for unaligned accesses in network byte order
173  * (big endian).
174  */
175 static inline void
176 write_uint16(void *dst, uint16_t data)
177 {
178 #ifdef ALLOW_UNALIGNED_ACCESSES
179 	* (uint16_t *) dst = htons(data);
180 #else
181 	uint8_t *p = (uint8_t *) dst;
182 	p[0] = (uint8_t) ((data >> 8) & 0xff);
183 	p[1] = (uint8_t) (data & 0xff);
184 #endif
185 }
186 
187 static inline void
188 write_uint32(void *dst, uint32_t data)
189 {
190 #ifdef ALLOW_UNALIGNED_ACCESSES
191 	* (uint32_t *) dst = htonl(data);
192 #else
193 	uint8_t *p = (uint8_t *) dst;
194 	p[0] = (uint8_t) ((data >> 24) & 0xff);
195 	p[1] = (uint8_t) ((data >> 16) & 0xff);
196 	p[2] = (uint8_t) ((data >> 8) & 0xff);
197 	p[3] = (uint8_t) (data & 0xff);
198 #endif
199 }
200 
201 static inline void
202 write_uint64(void *dst, uint64_t data)
203 {
204 	uint8_t *p = (uint8_t *) dst;
205 	p[0] = (uint8_t) ((data >> 56) & 0xff);
206 	p[1] = (uint8_t) ((data >> 48) & 0xff);
207 	p[2] = (uint8_t) ((data >> 40) & 0xff);
208 	p[3] = (uint8_t) ((data >> 32) & 0xff);
209 	p[4] = (uint8_t) ((data >> 24) & 0xff);
210 	p[5] = (uint8_t) ((data >> 16) & 0xff);
211 	p[6] = (uint8_t) ((data >> 8) & 0xff);
212 	p[7] = (uint8_t) (data & 0xff);
213 }
214 
215 /*
216  * Copy data allowing for unaligned accesses in network byte order
217  * (big endian).
218  */
219 static inline uint16_t
220 read_uint16(const void *src)
221 {
222 #ifdef ALLOW_UNALIGNED_ACCESSES
223 	return ntohs(* (uint16_t *) src);
224 #else
225 	uint8_t *p = (uint8_t *) src;
226 	return (p[0] << 8) | p[1];
227 #endif
228 }
229 
230 static inline uint32_t
231 read_uint32(const void *src)
232 {
233 #ifdef ALLOW_UNALIGNED_ACCESSES
234 	return ntohl(* (uint32_t *) src);
235 #else
236 	uint8_t *p = (uint8_t *) src;
237 	return (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3];
238 #endif
239 }
240 
241 static inline uint64_t
242 read_uint64(const void *src)
243 {
244 	uint8_t *p = (uint8_t *) src;
245 	return
246 	    ((uint64_t)p[0] << 56) |
247 	    ((uint64_t)p[1] << 48) |
248 	    ((uint64_t)p[2] << 40) |
249 	    ((uint64_t)p[3] << 32) |
250 	    ((uint64_t)p[4] << 24) |
251 	    ((uint64_t)p[5] << 16) |
252 	    ((uint64_t)p[6] <<  8) |
253 	    (uint64_t)p[7];
254 }
255 
256 /*
257  * Print debugging information using log_msg,
258  * set the logfile as /dev/stdout or /dev/stderr if you like.
259  * nsd -F 0xFFFF enables all debug facilities.
260  */
261 #define DEBUG_PARSER           0x0001U
262 #define DEBUG_ZONEC            0x0002U
263 #define DEBUG_QUERY            0x0004U
264 #define DEBUG_DBACCESS         0x0008U
265 #define DEBUG_NAME_COMPRESSION 0x0010U
266 #define DEBUG_XFRD             0x0020U
267 #define DEBUG_IPC              0x0040U
268 
269 extern unsigned nsd_debug_facilities;
270 extern int nsd_debug_level;
271 #ifdef NDEBUG
272 #define DEBUG(facility, level, args)  /* empty */
273 #else
274 #define DEBUG(facility, level, args)				\
275 	do {							\
276 		if ((facility) & nsd_debug_facilities &&	\
277 		    (level) <= nsd_debug_level) {		\
278 			log_msg args ;				\
279 		}						\
280 	} while (0)
281 #endif
282 
283 /* set to true to log time prettyprinted, or false to print epoch */
284 extern int log_time_asc;
285 
286 /*
287  * Timespec functions.
288  */
289 int timespec_compare(const struct timespec *left, const struct timespec *right);
290 void timespec_add(struct timespec *left, const struct timespec *right);
291 void timespec_subtract(struct timespec *left, const struct timespec *right);
292 
293 static inline void
294 timeval_to_timespec(struct timespec *left,
295 		    const struct timeval *right)
296 {
297 	left->tv_sec = right->tv_sec;
298 	left->tv_nsec = 1000 * right->tv_usec;
299 }
300 
301 /* get the time */
302 void get_time(struct timespec* t);
303 
304 /*
305  * Converts a string representation of a period of time into
306  * a long integer of seconds or serial value.
307  *
308  * Set the endptr to the first illegal character.
309  *
310  * Interface is similar as strtol(3)
311  *
312  * Returns:
313  *	LONG_MIN if underflow occurs
314  *	LONG_MAX if overflow occurs.
315  *	otherwise number of seconds
316  *
317  * XXX These functions do not check the range.
318  *
319  */
320 uint32_t strtoserial(const char *nptr, const char **endptr);
321 uint32_t strtottl(const char *nptr, const char **endptr);
322 
323 /*
324  * Convert binary data to a string of hexadecimal characters.
325  */
326 ssize_t hex_ntop(uint8_t const *src, size_t srclength, char *target,
327 		 size_t targsize);
328 ssize_t hex_pton(const char* src, uint8_t* target, size_t targsize);
329 
330 /*
331  * convert base32 data from and to string. Returns length.
332  * -1 on error. Use (byte count*8)%5==0.
333  */
334 int b32_pton(char const *src, uint8_t *target, size_t targsize);
335 int b32_ntop(uint8_t const *src, size_t srclength, char *target,
336 	size_t targsize);
337 
338 /*
339  * Strip trailing and leading whitespace from str.
340  */
341 void strip_string(char *str);
342 
343 /*
344  * Convert a single (hexadecimal) digit to its integer value.
345  */
346 int hexdigit_to_int(char ch);
347 
348 /*
349  * Convert TM to seconds since epoch (midnight, January 1st, 1970).
350  * Like timegm(3), which is not always available.
351  */
352 time_t mktime_from_utc(const struct tm *tm);
353 
354 /*
355  * Add bytes to given crc. Returns new CRC sum.
356  * Start crc val with 0xffffffff on first call. XOR crc with
357  * 0xffffffff at the end again to get final POSIX 1003.2 checksum.
358  */
359 uint32_t compute_crc(uint32_t crc, uint8_t* data, size_t len);
360 
361 /*
362  * Compares two 32-bit serial numbers as defined in RFC1982.  Returns
363  * <0 if a < b, 0 if a == b, and >0 if a > b.  The result is undefined
364  * if a != b but neither is greater or smaller (see RFC1982 section
365  * 3.2.).
366  */
367 int compare_serial(uint32_t a, uint32_t b);
368 
369 /*
370  * Generate a random query ID.
371  */
372 uint16_t qid_generate(void);
373 /* value between 0 .. (max-1) inclusive */
374 int random_generate(int max);
375 
376 /*
377  * call region_destroy on (region*)data, useful for region_add_cleanup().
378  */
379 void cleanup_region(void *data);
380 
381 /*
382  * Region used to store owner and origin of previous RR (used
383  * for pretty printing of zone data).
384  * Keep the same between calls to print_rr.
385  */
386 struct state_pretty_rr {
387 	struct region *previous_owner_region;
388 	const struct dname *previous_owner;
389 	const struct dname *previous_owner_origin;
390 };
391 struct state_pretty_rr* create_pretty_rr(struct region* region);
392 /* print rr to file, returns 0 on failure(nothing is written) */
393 int print_rr(FILE *out, struct state_pretty_rr* state, struct rr *record,
394 	struct region* tmp_region, struct buffer* tmp_buffer);
395 
396 /*
397  * Convert a numeric rcode value to a human readable string
398  */
399 const char* rcode2str(int rc);
400 
401 void addr2str(
402 #ifdef INET6
403 	struct sockaddr_storage *addr
404 #else
405 	struct sockaddr_in *addr
406 #endif
407 	, char* str, size_t len);
408 
409 #endif /* _UTIL_H_ */
410