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>
17struct rr;
18struct buffer;
19struct region;
20struct 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 */
44void 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 */
50void log_open(int option, int facility, const char *filename);
51
52/*
53 * Reopen the logfile.
54 */
55void log_reopen(const char *filename, uint8_t verbose);
56
57/*
58 * Finalize the logging system.
59 */
60void log_finalize(void);
61
62/*
63 * Type of function to use for the actual logging.
64 */
65typedef void log_function_type(int priority, const char *message);
66
67/*
68 * The function used to log to the log file.
69 */
70log_function_type log_file;
71
72/*
73 * The function used to log to syslog.  The messages are also logged
74 * using log_file.
75 */
76log_function_type log_syslog;
77
78/*
79 * The function used to log to syslog only.
80 */
81log_function_type log_only_syslog;
82
83/*
84 * Set the logging function to use (log_file or log_syslog).
85 */
86void log_set_log_function(log_function_type *log_function);
87
88/*
89 * Log a message using the current log function.
90 */
91void 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 */
97void log_vmsg(int priority, const char *format, va_list args);
98
99/*
100 * Verbose output switch
101 */
102extern 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 */
113void set_bit(uint8_t bits[], size_t index);
114
115/*
116 * Set the INDEXth bit of BITS to 0.
117 */
118void clear_bit(uint8_t bits[], size_t index);
119
120/*
121 * Return the value of the INDEXth bit of BITS.
122 */
123int get_bit(uint8_t bits[], size_t index);
124
125/* A general purpose lookup table */
126typedef struct lookup_table lookup_table_type;
127struct 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 */
135lookup_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 */
140lookup_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 */
147void *xalloc(size_t size);
148void *xmallocarray(size_t num, size_t size);
149void *xalloc_zero(size_t size);
150void *xalloc_array_zero(size_t num, size_t size);
151void *xrealloc(void *ptr, size_t size);
152char *xstrdup(const char *src);
153
154/*
155 * Mmap allocator routines.
156 *
157 */
158#ifdef USE_MMAP_ALLOC
159void *mmap_alloc(size_t size);
160void 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 */
168int write_data(FILE *file, const void *data, size_t size);
169
170/*
171 * like write_data, but keeps track of crc
172 */
173int 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 */
180int 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 */
186static inline void
187write_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
198static inline void
199write_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
212static inline void
213write_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 */
230static inline uint16_t
231read_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
241static inline uint32_t
242read_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
252static inline uint64_t
253read_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
280extern unsigned nsd_debug_facilities;
281extern 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 */
295extern int log_time_asc;
296
297/*
298 * Timespec functions.
299 */
300int timespec_compare(const struct timespec *left, const struct timespec *right);
301void timespec_add(struct timespec *left, const struct timespec *right);
302void timespec_subtract(struct timespec *left, const struct timespec *right);
303
304static inline void
305timeval_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 */
313void 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 */
331uint32_t strtoserial(const char *nptr, const char **endptr);
332uint32_t strtottl(const char *nptr, const char **endptr);
333
334/*
335 * Convert binary data to a string of hexadecimal characters.
336 */
337ssize_t hex_ntop(uint8_t const *src, size_t srclength, char *target,
338		 size_t targsize);
339ssize_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 */
345int b32_pton(char const *src, uint8_t *target, size_t targsize);
346int 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 */
352void strip_string(char *str);
353
354/*
355 * Convert a single (hexadecimal) digit to its integer value.
356 */
357int 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 */
363time_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 */
370uint32_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 */
378int compare_serial(uint32_t a, uint32_t b);
379
380/*
381 * Generate a random query ID.
382 */
383uint16_t qid_generate(void);
384/* value between 0 .. (max-1) inclusive */
385int random_generate(int max);
386
387/*
388 * call region_destroy on (region*)data, useful for region_add_cleanup().
389 */
390void 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 */
397struct state_pretty_rr {
398	struct region *previous_owner_region;
399	const struct dname *previous_owner;
400	const struct dname *previous_owner_origin;
401};
402struct state_pretty_rr* create_pretty_rr(struct region* region);
403/* print rr to file, returns 0 on failure(nothing is written) */
404int 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 */
410const char* rcode2str(int rc);
411
412void 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 */
421void 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 */
431void append_trailing_slash(const char** dirname, struct region* region);
432
433/** true if filename starts with chroot or is not absolute */
434int file_inside_chroot(const char* fname, const char* chr);
435
436/** Something went wrong, give error messages and exit. */
437void error(const char *format, ...) ATTR_FORMAT(printf, 1, 2) ATTR_NORETURN;
438
439#if HAVE_CPUSET_T
440int number_of_cpus(void);
441int 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. */
448void add_cookie_secret(struct nsd* nsd, uint8_t* secret);
449/* Makes the staging cookie secret active and the active secret staging. */
450void activate_cookie_secret(struct nsd* nsd);
451/* Drop a cookie secret. Drops the staging secret. An active secret will not
452 * be dropped. */
453void drop_cookie_secret(struct nsd* nsd);
454#endif /* UTIL_H */
455