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