xref: /openbsd-src/usr.sbin/nsd/util.h (revision 4c1e55dc91edd6e69ccc60ce855900fbc12cf34f)
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 /* Counter for statistics */
35 typedef unsigned long stc_t;
36 
37 /**
38  * Statistics.
39  *
40  */
41 struct nsdst {
42 	time_t  boot;
43 	int     period;         /* Produce statistics dump every st_period seconds */
44 	stc_t   qtype[257];     /* Counters per qtype */
45 	stc_t   qclass[4];      /* Class IN or Class CH or other */
46 	stc_t   qudp, qudp6;    /* Number of queries udp and udp6 */
47 	stc_t   ctcp, ctcp6;    /* Number of tcp and tcp6 connections */
48 	stc_t   rcode[17], opcode[6]; /* Rcodes & opcodes */
49 	/* Dropped, truncated, queries for nonconfigured zone, tx errors */
50 	stc_t   dropped, truncated, wrongzone, txerr, rxerr;
51 	stc_t   edns, ednserr, raxfr, nona;
52 };
53 
54 /*
55  * Initialize the logging system.  All messages are logged to stderr
56  * until log_open and log_set_log_function are called.
57  */
58 void log_init(const char *ident);
59 
60 /*
61  * Open the system log.  If FILENAME is not NULL, a log file is opened
62  * as well.
63  */
64 void log_open(int option, int facility, const char *filename);
65 
66 /*
67  * Reopen the logfile.
68  */
69 void log_reopen(const char *filename, uint8_t verbose);
70 
71 /*
72  * Finalize the logging system.
73  */
74 void log_finalize(void);
75 
76 /*
77  * Type of function to use for the actual logging.
78  */
79 typedef void log_function_type(int priority, const char *message);
80 
81 /*
82  * The function used to log to the log file.
83  */
84 log_function_type log_file;
85 
86 /*
87  * The function used to log to syslog.  The messages are also logged
88  * using log_file.
89  */
90 log_function_type log_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 *xalloc_zero(size_t size);
158 void *xrealloc(void *ptr, size_t size);
159 
160 /*
161  * Mmap allocator routines.
162  *
163  */
164 #ifdef USE_MMAP_ALLOC
165 void *mmap_alloc(size_t size);
166 void mmap_free(void *ptr);
167 #endif /* USE_MMAP_ALLOC */
168 
169 /*
170  * Write SIZE bytes of DATA to FILE.  Report an error on failure.
171  *
172  * Returns 0 on failure, 1 on success.
173  */
174 int write_data(FILE *file, const void *data, size_t size);
175 
176 /*
177  * like write_data, but keeps track of crc
178  */
179 int write_data_crc(FILE *file, const void *data, size_t size, uint32_t* crc);
180 
181 /*
182  * Write the complete buffer to the socket, irrespective of short
183  * writes or interrupts. This function blocks to write the data.
184  * Returns 0 on error, 1 on success.
185  */
186 int write_socket(int s, const void *data, size_t size);
187 
188 /*
189  * Copy data allowing for unaligned accesses in network byte order
190  * (big endian).
191  */
192 static inline void
193 write_uint16(void *dst, uint16_t data)
194 {
195 #ifdef ALLOW_UNALIGNED_ACCESSES
196 	* (uint16_t *) dst = htons(data);
197 #else
198 	uint8_t *p = (uint8_t *) dst;
199 	p[0] = (uint8_t) ((data >> 8) & 0xff);
200 	p[1] = (uint8_t) (data & 0xff);
201 #endif
202 }
203 
204 static inline void
205 write_uint32(void *dst, uint32_t data)
206 {
207 #ifdef ALLOW_UNALIGNED_ACCESSES
208 	* (uint32_t *) dst = htonl(data);
209 #else
210 	uint8_t *p = (uint8_t *) dst;
211 	p[0] = (uint8_t) ((data >> 24) & 0xff);
212 	p[1] = (uint8_t) ((data >> 16) & 0xff);
213 	p[2] = (uint8_t) ((data >> 8) & 0xff);
214 	p[3] = (uint8_t) (data & 0xff);
215 #endif
216 }
217 
218 /*
219  * Copy data allowing for unaligned accesses in network byte order
220  * (big endian).
221  */
222 static inline uint16_t
223 read_uint16(const void *src)
224 {
225 #ifdef ALLOW_UNALIGNED_ACCESSES
226 	return ntohs(* (uint16_t *) src);
227 #else
228 	uint8_t *p = (uint8_t *) src;
229 	return (p[0] << 8) | p[1];
230 #endif
231 }
232 
233 static inline uint32_t
234 read_uint32(const void *src)
235 {
236 #ifdef ALLOW_UNALIGNED_ACCESSES
237 	return ntohl(* (uint32_t *) src);
238 #else
239 	uint8_t *p = (uint8_t *) src;
240 	return (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3];
241 #endif
242 }
243 
244 /*
245  * Print debugging information using log_msg,
246  * set the logfile as /dev/stdout or /dev/stderr if you like.
247  * nsd -F 0xFFFF enables all debug facilities.
248  */
249 #define DEBUG_PARSER           0x0001U
250 #define DEBUG_ZONEC            0x0002U
251 #define DEBUG_QUERY            0x0004U
252 #define DEBUG_DBACCESS         0x0008U
253 #define DEBUG_NAME_COMPRESSION 0x0010U
254 #define DEBUG_XFRD             0x0020U
255 #define DEBUG_IPC              0x0040U
256 
257 extern unsigned nsd_debug_facilities;
258 extern int nsd_debug_level;
259 #ifdef NDEBUG
260 #define DEBUG(facility, level, args)  /* empty */
261 #else
262 #define DEBUG(facility, level, args)				\
263 	do {							\
264 		if ((facility) & nsd_debug_facilities &&	\
265 		    (level) <= nsd_debug_level) {		\
266 			log_msg args ;				\
267 		}						\
268 	} while (0)
269 #endif
270 
271 
272 /*
273  * Timespec functions.
274  */
275 int timespec_compare(const struct timespec *left, const struct timespec *right);
276 void timespec_add(struct timespec *left, const struct timespec *right);
277 void timespec_subtract(struct timespec *left, const struct timespec *right);
278 
279 static inline void
280 timeval_to_timespec(struct timespec *left,
281 		    const struct timeval *right)
282 {
283 	left->tv_sec = right->tv_sec;
284 	left->tv_nsec = 1000 * right->tv_usec;
285 }
286 
287 
288 /*
289  * Converts a string representation of a period of time into
290  * a long integer of seconds or serial value.
291  *
292  * Set the endptr to the first illegal character.
293  *
294  * Interface is similar as strtol(3)
295  *
296  * Returns:
297  *	LONG_MIN if underflow occurs
298  *	LONG_MAX if overflow occurs.
299  *	otherwise number of seconds
300  *
301  * XXX These functions do not check the range.
302  *
303  */
304 uint32_t strtoserial(const char *nptr, const char **endptr);
305 uint32_t strtottl(const char *nptr, const char **endptr);
306 
307 /*
308  * Convert binary data to a string of hexadecimal characters.
309  */
310 ssize_t hex_ntop(uint8_t const *src, size_t srclength, char *target,
311 		 size_t targsize);
312 ssize_t hex_pton(const char* src, uint8_t* target, size_t targsize);
313 
314 /*
315  * convert base32 data from and to string. Returns length.
316  * -1 on error. Use (byte count*8)%5==0.
317  */
318 int b32_pton(char const *src, uint8_t *target, size_t targsize);
319 int b32_ntop(uint8_t const *src, size_t srclength, char *target,
320 	size_t targsize);
321 
322 /*
323  * Strip trailing and leading whitespace from str.
324  */
325 void strip_string(char *str);
326 
327 /*
328  * Convert a single (hexidecimal) digit to its integer value.
329  */
330 int hexdigit_to_int(char ch);
331 
332 /*
333  * Convert TM to seconds since epoch (midnight, January 1st, 1970).
334  * Like timegm(3), which is not always available.
335  */
336 time_t mktime_from_utc(const struct tm *tm);
337 
338 /*
339  * Add bytes to given crc. Returns new CRC sum.
340  * Start crc val with 0xffffffff on first call. XOR crc with
341  * 0xffffffff at the end again to get final POSIX 1003.2 checksum.
342  */
343 uint32_t compute_crc(uint32_t crc, uint8_t* data, size_t len);
344 
345 /*
346  * Compares two 32-bit serial numbers as defined in RFC1982.  Returns
347  * <0 if a < b, 0 if a == b, and >0 if a > b.  The result is undefined
348  * if a != b but neither is greater or smaller (see RFC1982 section
349  * 3.2.).
350  */
351 int compare_serial(uint32_t a, uint32_t b);
352 
353 /*
354  * Generate a random query ID.
355  */
356 uint16_t qid_generate(void);
357 
358 /*
359  * call region_destroy on (region*)data, useful for region_add_cleanup().
360  */
361 void cleanup_region(void *data);
362 
363 /*
364  * Region used to store owner and origin of previous RR (used
365  * for pretty printing of zone data).
366  * Keep the same between calls to print_rr.
367  */
368 struct state_pretty_rr {
369 	struct region *previous_owner_region;
370 	const struct dname *previous_owner;
371 	const struct dname *previous_owner_origin;
372 };
373 struct state_pretty_rr* create_pretty_rr(struct region* region);
374 /* print rr to file, returns 0 on failure(nothing is written) */
375 int print_rr(FILE *out, struct state_pretty_rr* state, struct rr *record);
376 
377 /*
378  * Convert a numeric rcode value to a human readable string
379  */
380 const char* rcode2str(int rc);
381 
382 /*
383  * Stack of pointers.
384  * Stack is fixed size on start. More elems fall off stack.
385  */
386 struct stack {
387 	void** data;
388 	size_t num, capacity;
389 };
390 typedef struct stack stack_type;
391 stack_type* stack_create(struct region* region, size_t size);
392 void stack_push(stack_type* stack, void* elem);
393 void* stack_pop(stack_type* stack);
394 int addr2ip(
395 #ifdef INET6
396 	struct sockaddr_storage addr
397 #else
398 	struct sockaddr_in addr
399 #endif
400 , char address[], socklen_t size);
401 
402 #endif /* _UTIL_H_ */
403