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