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#ifdef USE_LOG_PROCESS_ROLE
47/*
48 * Set the name of the role for the process (for debugging purposes)
49 */
50void 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 */
59void log_open(int option, int facility, const char *filename);
60
61/*
62 * Reopen the logfile.
63 */
64void log_reopen(const char *filename, uint8_t verbose);
65
66/*
67 * Finalize the logging system.
68 */
69void log_finalize(void);
70
71/*
72 * Type of function to use for the actual logging.
73 */
74typedef void log_function_type(int priority, const char *message);
75
76/*
77 * The function used to log to the log file.
78 */
79log_function_type log_file;
80
81/*
82 * The function used to log to syslog.  The messages are also logged
83 * using log_file.
84 */
85log_function_type log_syslog;
86
87/*
88 * The function used to log to syslog only.
89 */
90log_function_type log_only_syslog;
91
92/*
93 * Set the logging function to use (log_file or log_syslog).
94 */
95void log_set_log_function(log_function_type *log_function);
96
97/*
98 * Log a message using the current log function.
99 */
100void 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 */
106void log_vmsg(int priority, const char *format, va_list args);
107
108/*
109 * Verbose output switch
110 */
111extern 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 */
122void set_bit(uint8_t bits[], size_t index);
123
124/*
125 * Set the INDEXth bit of BITS to 0.
126 */
127void clear_bit(uint8_t bits[], size_t index);
128
129/*
130 * Return the value of the INDEXth bit of BITS.
131 */
132int get_bit(uint8_t bits[], size_t index);
133
134/* A general purpose lookup table */
135typedef struct lookup_table lookup_table_type;
136struct 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 */
144lookup_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 */
149lookup_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 */
156void *xalloc(size_t size);
157void *xmallocarray(size_t num, size_t size);
158void *xalloc_zero(size_t size);
159void *xalloc_array_zero(size_t num, size_t size);
160void *xrealloc(void *ptr, size_t size);
161char *xstrdup(const char *src);
162
163/*
164 * Mmap allocator routines.
165 *
166 */
167#ifdef USE_MMAP_ALLOC
168void *mmap_alloc(size_t size);
169void 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 */
177int write_data(FILE *file, const void *data, size_t size);
178
179/*
180 * like write_data, but keeps track of crc
181 */
182int 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 */
189int 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 */
195static inline void
196write_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
207static inline void
208write_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
221static inline void
222write_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 */
239static inline uint16_t
240read_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
250static inline uint32_t
251read_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
261static inline uint64_t
262read_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
289extern unsigned nsd_debug_facilities;
290extern 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 */
304extern int log_time_asc;
305
306/*
307 * Timespec functions.
308 */
309int timespec_compare(const struct timespec *left, const struct timespec *right);
310void timespec_add(struct timespec *left, const struct timespec *right);
311void timespec_subtract(struct timespec *left, const struct timespec *right);
312
313static inline void
314timeval_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 */
322void 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 */
340uint32_t strtoserial(const char *nptr, const char **endptr);
341uint32_t strtottl(const char *nptr, const char **endptr);
342
343/*
344 * Convert binary data to a string of hexadecimal characters.
345 */
346ssize_t hex_ntop(uint8_t const *src, size_t srclength, char *target,
347		 size_t targsize);
348ssize_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 */
354int b32_pton(char const *src, uint8_t *target, size_t targsize);
355int 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 */
361void strip_string(char *str);
362
363/*
364 * Convert a single (hexadecimal) digit to its integer value.
365 */
366int 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 */
372time_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 */
379uint32_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 */
387int compare_serial(uint32_t a, uint32_t b);
388
389/*
390 * Generate a random query ID.
391 */
392uint16_t qid_generate(void);
393/* value between 0 .. (max-1) inclusive */
394int random_generate(int max);
395
396/*
397 * call region_destroy on (region*)data, useful for region_add_cleanup().
398 */
399void 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 */
406struct state_pretty_rr {
407	struct region *previous_owner_region;
408	const struct dname *previous_owner;
409	const struct dname *previous_owner_origin;
410};
411struct state_pretty_rr* create_pretty_rr(struct region* region);
412/* print rr to file, returns 0 on failure(nothing is written) */
413int 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 */
419const char* rcode2str(int rc);
420
421void 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 */
430void 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 */
440void append_trailing_slash(const char** dirname, struct region* region);
441
442/** true if filename starts with chroot or is not absolute */
443int file_inside_chroot(const char* fname, const char* chr);
444
445/** Something went wrong, give error messages and exit. */
446void error(const char *format, ...) ATTR_FORMAT(printf, 1, 2) ATTR_NORETURN;
447
448#if HAVE_CPUSET_T
449int number_of_cpus(void);
450int 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. */
457void add_cookie_secret(struct nsd* nsd, uint8_t* secret);
458/* Makes the staging cookie secret active and the active secret staging. */
459void activate_cookie_secret(struct nsd* nsd);
460/* Drop a cookie secret. Drops the staging secret. An active secret will not
461 * be dropped. */
462void drop_cookie_secret(struct nsd* nsd);
463#endif /* UTIL_H */
464