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