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> 17 struct rr; 18 struct buffer; 19 struct 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 */ 43 void 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 */ 49 void log_open(int option, int facility, const char *filename); 50 51 /* 52 * Reopen the logfile. 53 */ 54 void log_reopen(const char *filename, uint8_t verbose); 55 56 /* 57 * Finalize the logging system. 58 */ 59 void log_finalize(void); 60 61 /* 62 * Type of function to use for the actual logging. 63 */ 64 typedef void log_function_type(int priority, const char *message); 65 66 /* 67 * The function used to log to the log file. 68 */ 69 log_function_type log_file; 70 71 /* 72 * The function used to log to syslog. The messages are also logged 73 * using log_file. 74 */ 75 log_function_type log_syslog; 76 77 /* 78 * The function used to log to syslog only. 79 */ 80 log_function_type log_only_syslog; 81 82 /* 83 * Set the logging function to use (log_file or log_syslog). 84 */ 85 void log_set_log_function(log_function_type *log_function); 86 87 /* 88 * Log a message using the current log function. 89 */ 90 void log_msg(int priority, const char *format, ...) 91 ATTR_FORMAT(printf, 2, 3); 92 93 /* 94 * Log a message using the current log function. 95 */ 96 void log_vmsg(int priority, const char *format, va_list args); 97 98 /* 99 * Verbose output switch 100 */ 101 extern int verbosity; 102 #define VERBOSITY(level, args) \ 103 do { \ 104 if ((level) <= verbosity) { \ 105 log_msg args ; \ 106 } \ 107 } while (0) 108 109 /* 110 * Set the INDEXth bit of BITS to 1. 111 */ 112 void set_bit(uint8_t bits[], size_t index); 113 114 /* 115 * Set the INDEXth bit of BITS to 0. 116 */ 117 void clear_bit(uint8_t bits[], size_t index); 118 119 /* 120 * Return the value of the INDEXth bit of BITS. 121 */ 122 int get_bit(uint8_t bits[], size_t index); 123 124 /* A general purpose lookup table */ 125 typedef struct lookup_table lookup_table_type; 126 struct lookup_table { 127 int id; 128 const char *name; 129 }; 130 131 /* 132 * Looks up the table entry by name, returns NULL if not found. 133 */ 134 lookup_table_type *lookup_by_name(lookup_table_type table[], const char *name); 135 136 /* 137 * Looks up the table entry by id, returns NULL if not found. 138 */ 139 lookup_table_type *lookup_by_id(lookup_table_type table[], int id); 140 141 /* 142 * (Re-)allocate SIZE bytes of memory. Report an error if the memory 143 * could not be allocated and exit the program. These functions never 144 * return NULL. 145 */ 146 void *xalloc(size_t size); 147 void *xmallocarray(size_t num, size_t size); 148 void *xalloc_zero(size_t size); 149 void *xalloc_array_zero(size_t num, size_t size); 150 void *xrealloc(void *ptr, size_t size); 151 char *xstrdup(const char *src); 152 153 /* 154 * Mmap allocator routines. 155 * 156 */ 157 #ifdef USE_MMAP_ALLOC 158 void *mmap_alloc(size_t size); 159 void mmap_free(void *ptr); 160 #endif /* USE_MMAP_ALLOC */ 161 162 /* 163 * Write SIZE bytes of DATA to FILE. Report an error on failure. 164 * 165 * Returns 0 on failure, 1 on success. 166 */ 167 int write_data(FILE *file, const void *data, size_t size); 168 169 /* 170 * like write_data, but keeps track of crc 171 */ 172 int write_data_crc(FILE *file, const void *data, size_t size, uint32_t* crc); 173 174 /* 175 * Write the complete buffer to the socket, irrespective of short 176 * writes or interrupts. This function blocks to write the data. 177 * Returns 0 on error, 1 on success. 178 */ 179 int write_socket(int s, const void *data, size_t size); 180 181 /* 182 * Copy data allowing for unaligned accesses in network byte order 183 * (big endian). 184 */ 185 static inline void 186 write_uint16(void *dst, uint16_t data) 187 { 188 #ifdef ALLOW_UNALIGNED_ACCESSES 189 * (uint16_t *) dst = htons(data); 190 #else 191 uint8_t *p = (uint8_t *) dst; 192 p[0] = (uint8_t) ((data >> 8) & 0xff); 193 p[1] = (uint8_t) (data & 0xff); 194 #endif 195 } 196 197 static inline void 198 write_uint32(void *dst, uint32_t data) 199 { 200 #ifdef ALLOW_UNALIGNED_ACCESSES 201 * (uint32_t *) dst = htonl(data); 202 #else 203 uint8_t *p = (uint8_t *) dst; 204 p[0] = (uint8_t) ((data >> 24) & 0xff); 205 p[1] = (uint8_t) ((data >> 16) & 0xff); 206 p[2] = (uint8_t) ((data >> 8) & 0xff); 207 p[3] = (uint8_t) (data & 0xff); 208 #endif 209 } 210 211 static inline void 212 write_uint64(void *dst, uint64_t data) 213 { 214 uint8_t *p = (uint8_t *) dst; 215 p[0] = (uint8_t) ((data >> 56) & 0xff); 216 p[1] = (uint8_t) ((data >> 48) & 0xff); 217 p[2] = (uint8_t) ((data >> 40) & 0xff); 218 p[3] = (uint8_t) ((data >> 32) & 0xff); 219 p[4] = (uint8_t) ((data >> 24) & 0xff); 220 p[5] = (uint8_t) ((data >> 16) & 0xff); 221 p[6] = (uint8_t) ((data >> 8) & 0xff); 222 p[7] = (uint8_t) (data & 0xff); 223 } 224 225 /* 226 * Copy data allowing for unaligned accesses in network byte order 227 * (big endian). 228 */ 229 static inline uint16_t 230 read_uint16(const void *src) 231 { 232 #ifdef ALLOW_UNALIGNED_ACCESSES 233 return ntohs(* (const uint16_t *) src); 234 #else 235 const uint8_t *p = (const uint8_t *) src; 236 return (p[0] << 8) | p[1]; 237 #endif 238 } 239 240 static inline uint32_t 241 read_uint32(const void *src) 242 { 243 #ifdef ALLOW_UNALIGNED_ACCESSES 244 return ntohl(* (const uint32_t *) src); 245 #else 246 const uint8_t *p = (const uint8_t *) src; 247 return (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3]; 248 #endif 249 } 250 251 static inline uint64_t 252 read_uint64(const void *src) 253 { 254 const uint8_t *p = (const uint8_t *) src; 255 return 256 ((uint64_t)p[0] << 56) | 257 ((uint64_t)p[1] << 48) | 258 ((uint64_t)p[2] << 40) | 259 ((uint64_t)p[3] << 32) | 260 ((uint64_t)p[4] << 24) | 261 ((uint64_t)p[5] << 16) | 262 ((uint64_t)p[6] << 8) | 263 (uint64_t)p[7]; 264 } 265 266 /* 267 * Print debugging information using log_msg, 268 * set the logfile as /dev/stdout or /dev/stderr if you like. 269 * nsd -F 0xFFFF enables all debug facilities. 270 */ 271 #define DEBUG_PARSER 0x0001U 272 #define DEBUG_ZONEC 0x0002U 273 #define DEBUG_QUERY 0x0004U 274 #define DEBUG_DBACCESS 0x0008U 275 #define DEBUG_NAME_COMPRESSION 0x0010U 276 #define DEBUG_XFRD 0x0020U 277 #define DEBUG_IPC 0x0040U 278 279 extern unsigned nsd_debug_facilities; 280 extern int nsd_debug_level; 281 #ifdef NDEBUG 282 #define DEBUG(facility, level, args) /* empty */ 283 #else 284 #define DEBUG(facility, level, args) \ 285 do { \ 286 if ((facility) & nsd_debug_facilities && \ 287 (level) <= nsd_debug_level) { \ 288 log_msg args ; \ 289 } \ 290 } while (0) 291 #endif 292 293 /* set to true to log time prettyprinted, or false to print epoch */ 294 extern int log_time_asc; 295 296 /* 297 * Timespec functions. 298 */ 299 int timespec_compare(const struct timespec *left, const struct timespec *right); 300 void timespec_add(struct timespec *left, const struct timespec *right); 301 void timespec_subtract(struct timespec *left, const struct timespec *right); 302 303 static inline void 304 timeval_to_timespec(struct timespec *left, 305 const struct timeval *right) 306 { 307 left->tv_sec = right->tv_sec; 308 left->tv_nsec = 1000 * right->tv_usec; 309 } 310 311 /* get the time */ 312 void get_time(struct timespec* t); 313 314 /* 315 * Converts a string representation of a period of time into 316 * a long integer of seconds or serial value. 317 * 318 * Set the endptr to the first illegal character. 319 * 320 * Interface is similar as strtol(3) 321 * 322 * Returns: 323 * LONG_MIN if underflow occurs 324 * LONG_MAX if overflow occurs. 325 * otherwise number of seconds 326 * 327 * XXX These functions do not check the range. 328 * 329 */ 330 uint32_t strtoserial(const char *nptr, const char **endptr); 331 uint32_t strtottl(const char *nptr, const char **endptr); 332 333 /* 334 * Convert binary data to a string of hexadecimal characters. 335 */ 336 ssize_t hex_ntop(uint8_t const *src, size_t srclength, char *target, 337 size_t targsize); 338 ssize_t hex_pton(const char* src, uint8_t* target, size_t targsize); 339 340 /* 341 * convert base32 data from and to string. Returns length. 342 * -1 on error. Use (byte count*8)%5==0. 343 */ 344 int b32_pton(char const *src, uint8_t *target, size_t targsize); 345 int b32_ntop(uint8_t const *src, size_t srclength, char *target, 346 size_t targsize); 347 348 /* 349 * Strip trailing and leading whitespace from str. 350 */ 351 void strip_string(char *str); 352 353 /* 354 * Convert a single (hexadecimal) digit to its integer value. 355 */ 356 int hexdigit_to_int(char ch); 357 358 /* 359 * Convert TM to seconds since epoch (midnight, January 1st, 1970). 360 * Like timegm(3), which is not always available. 361 */ 362 time_t mktime_from_utc(const struct tm *tm); 363 364 /* 365 * Add bytes to given crc. Returns new CRC sum. 366 * Start crc val with 0xffffffff on first call. XOR crc with 367 * 0xffffffff at the end again to get final POSIX 1003.2 checksum. 368 */ 369 uint32_t compute_crc(uint32_t crc, uint8_t* data, size_t len); 370 371 /* 372 * Compares two 32-bit serial numbers as defined in RFC1982. Returns 373 * <0 if a < b, 0 if a == b, and >0 if a > b. The result is undefined 374 * if a != b but neither is greater or smaller (see RFC1982 section 375 * 3.2.). 376 */ 377 int compare_serial(uint32_t a, uint32_t b); 378 379 /* 380 * Generate a random query ID. 381 */ 382 uint16_t qid_generate(void); 383 /* value between 0 .. (max-1) inclusive */ 384 int random_generate(int max); 385 386 /* 387 * call region_destroy on (region*)data, useful for region_add_cleanup(). 388 */ 389 void cleanup_region(void *data); 390 391 /* 392 * Region used to store owner and origin of previous RR (used 393 * for pretty printing of zone data). 394 * Keep the same between calls to print_rr. 395 */ 396 struct state_pretty_rr { 397 struct region *previous_owner_region; 398 const struct dname *previous_owner; 399 const struct dname *previous_owner_origin; 400 }; 401 struct state_pretty_rr* create_pretty_rr(struct region* region); 402 /* print rr to file, returns 0 on failure(nothing is written) */ 403 int print_rr(FILE *out, struct state_pretty_rr* state, struct rr *record, 404 struct region* tmp_region, struct buffer* tmp_buffer); 405 406 /* 407 * Convert a numeric rcode value to a human readable string 408 */ 409 const char* rcode2str(int rc); 410 411 void addr2str( 412 #ifdef INET6 413 struct sockaddr_storage *addr 414 #else 415 struct sockaddr_in *addr 416 #endif 417 , char* str, size_t len); 418 419 /* print addr@port */ 420 void addrport2str( 421 #ifdef INET6 422 struct sockaddr_storage *addr 423 #else 424 struct sockaddr_in *addr 425 #endif 426 , char* str, size_t len); 427 428 /** copy dirname string and append slash. Previous dirname is leaked, 429 * but it is to be used once, at startup, for chroot */ 430 void append_trailing_slash(const char** dirname, struct region* region); 431 432 /** true if filename starts with chroot or is not absolute */ 433 int file_inside_chroot(const char* fname, const char* chr); 434 435 /** Something went wrong, give error messages and exit. */ 436 void error(const char *format, ...) ATTR_FORMAT(printf, 1, 2) ATTR_NORETURN; 437 438 #if HAVE_CPUSET_T 439 int number_of_cpus(void); 440 int set_cpu_affinity(cpuset_t *set); 441 #endif 442 443 #endif /* _UTIL_H_ */ 444