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