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