util.h revision 1.5
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;
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 */
43void 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 */
49void log_open(int option, int facility, const char *filename);
50
51/*
52 * Reopen the logfile.
53 */
54void log_reopen(const char *filename, uint8_t verbose);
55
56/*
57 * Finalize the logging system.
58 */
59void log_finalize(void);
60
61/*
62 * Type of function to use for the actual logging.
63 */
64typedef void log_function_type(int priority, const char *message);
65
66/*
67 * The function used to log to the log file.
68 */
69log_function_type log_file;
70
71/*
72 * The function used to log to syslog.  The messages are also logged
73 * using log_file.
74 */
75log_function_type log_syslog;
76
77/*
78 * Set the logging function to use (log_file or log_syslog).
79 */
80void log_set_log_function(log_function_type *log_function);
81
82/*
83 * Log a message using the current log function.
84 */
85void 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 */
91void log_vmsg(int priority, const char *format, va_list args);
92
93/*
94 * Verbose output switch
95 */
96extern 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 */
107void set_bit(uint8_t bits[], size_t index);
108
109/*
110 * Set the INDEXth bit of BITS to 0.
111 */
112void clear_bit(uint8_t bits[], size_t index);
113
114/*
115 * Return the value of the INDEXth bit of BITS.
116 */
117int get_bit(uint8_t bits[], size_t index);
118
119/* A general purpose lookup table */
120typedef struct lookup_table lookup_table_type;
121struct 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 */
129lookup_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 */
134lookup_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 */
141void *xalloc(size_t size);
142void *xmallocarray(size_t num, size_t size);
143void *xalloc_zero(size_t size);
144void *xalloc_array_zero(size_t num, size_t size);
145void *xrealloc(void *ptr, size_t size);
146
147/*
148 * Mmap allocator routines.
149 *
150 */
151#ifdef USE_MMAP_ALLOC
152void *mmap_alloc(size_t size);
153void 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 */
161int write_data(FILE *file, const void *data, size_t size);
162
163/*
164 * like write_data, but keeps track of crc
165 */
166int 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 */
173int 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 */
179static inline void
180write_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
191static inline void
192write_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
205static inline void
206write_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 */
223static inline uint16_t
224read_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
234static inline uint32_t
235read_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
245static inline uint64_t
246read_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
273extern unsigned nsd_debug_facilities;
274extern int nsd_debug_level;
275#undef DEBUG	/* XXX */
276#ifdef NDEBUG
277#define DEBUG(facility, level, args)  /* empty */
278#else
279#define DEBUG(facility, level, args)				\
280	do {							\
281		if ((facility) & nsd_debug_facilities &&	\
282		    (level) <= nsd_debug_level) {		\
283			log_msg args ;				\
284		}						\
285	} while (0)
286#endif
287
288/* set to true to log time prettyprinted, or false to print epoch */
289extern int log_time_asc;
290
291/*
292 * Timespec functions.
293 */
294int timespec_compare(const struct timespec *left, const struct timespec *right);
295void timespec_add(struct timespec *left, const struct timespec *right);
296void timespec_subtract(struct timespec *left, const struct timespec *right);
297
298static inline void
299timeval_to_timespec(struct timespec *left,
300		    const struct timeval *right)
301{
302	left->tv_sec = right->tv_sec;
303	left->tv_nsec = 1000 * right->tv_usec;
304}
305
306/* get the time */
307void get_time(struct timespec* t);
308
309/*
310 * Converts a string representation of a period of time into
311 * a long integer of seconds or serial value.
312 *
313 * Set the endptr to the first illegal character.
314 *
315 * Interface is similar as strtol(3)
316 *
317 * Returns:
318 *	LONG_MIN if underflow occurs
319 *	LONG_MAX if overflow occurs.
320 *	otherwise number of seconds
321 *
322 * XXX These functions do not check the range.
323 *
324 */
325uint32_t strtoserial(const char *nptr, const char **endptr);
326uint32_t strtottl(const char *nptr, const char **endptr);
327
328/*
329 * Convert binary data to a string of hexadecimal characters.
330 */
331ssize_t hex_ntop(uint8_t const *src, size_t srclength, char *target,
332		 size_t targsize);
333ssize_t hex_pton(const char* src, uint8_t* target, size_t targsize);
334
335/*
336 * convert base32 data from and to string. Returns length.
337 * -1 on error. Use (byte count*8)%5==0.
338 */
339int b32_pton(char const *src, uint8_t *target, size_t targsize);
340int b32_ntop(uint8_t const *src, size_t srclength, char *target,
341	size_t targsize);
342
343/*
344 * Strip trailing and leading whitespace from str.
345 */
346void strip_string(char *str);
347
348/*
349 * Convert a single (hexadecimal) digit to its integer value.
350 */
351int hexdigit_to_int(char ch);
352
353/*
354 * Convert TM to seconds since epoch (midnight, January 1st, 1970).
355 * Like timegm(3), which is not always available.
356 */
357time_t mktime_from_utc(const struct tm *tm);
358
359/*
360 * Add bytes to given crc. Returns new CRC sum.
361 * Start crc val with 0xffffffff on first call. XOR crc with
362 * 0xffffffff at the end again to get final POSIX 1003.2 checksum.
363 */
364uint32_t compute_crc(uint32_t crc, uint8_t* data, size_t len);
365
366/*
367 * Compares two 32-bit serial numbers as defined in RFC1982.  Returns
368 * <0 if a < b, 0 if a == b, and >0 if a > b.  The result is undefined
369 * if a != b but neither is greater or smaller (see RFC1982 section
370 * 3.2.).
371 */
372int compare_serial(uint32_t a, uint32_t b);
373
374/*
375 * Generate a random query ID.
376 */
377uint16_t qid_generate(void);
378/* value between 0 .. (max-1) inclusive */
379int random_generate(int max);
380
381/*
382 * call region_destroy on (region*)data, useful for region_add_cleanup().
383 */
384void cleanup_region(void *data);
385
386/*
387 * Region used to store owner and origin of previous RR (used
388 * for pretty printing of zone data).
389 * Keep the same between calls to print_rr.
390 */
391struct state_pretty_rr {
392	struct region *previous_owner_region;
393	const struct dname *previous_owner;
394	const struct dname *previous_owner_origin;
395};
396struct state_pretty_rr* create_pretty_rr(struct region* region);
397/* print rr to file, returns 0 on failure(nothing is written) */
398int print_rr(FILE *out, struct state_pretty_rr* state, struct rr *record,
399	struct region* tmp_region, struct buffer* tmp_buffer);
400
401/*
402 * Convert a numeric rcode value to a human readable string
403 */
404const char* rcode2str(int rc);
405
406void addr2str(
407#ifdef INET6
408	struct sockaddr_storage *addr
409#else
410	struct sockaddr_in *addr
411#endif
412	, char* str, size_t len);
413
414/* print addr@port */
415void addrport2str(
416#ifdef INET6
417	struct sockaddr_storage *addr
418#else
419	struct sockaddr_in *addr
420#endif
421	, char* str, size_t len);
422
423/** copy dirname string and append slash.  Previous dirname is leaked,
424 * but it is to be used once, at startup, for chroot */
425void append_trailing_slash(const char** dirname, struct region* region);
426
427/** true if filename starts with chroot or is not absolute */
428int file_inside_chroot(const char* fname, const char* chr);
429
430/** Something went wrong, give error messages and exit. */
431void error(const char *format, ...) ATTR_FORMAT(printf, 1, 2) ATTR_NORETURN;
432
433#endif /* _UTIL_H_ */
434