util.h revision 1.4
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/** copy dirname string and append slash. Previous dirname is leaked, 415 * but it is to be used once, at startup, for chroot */ 416void append_trailing_slash(const char** dirname, struct region* region); 417 418/** true if filename starts with chroot or is not absolute */ 419int file_inside_chroot(const char* fname, const char* chr); 420 421/** Something went wrong, give error messages and exit. */ 422void error(const char *format, ...) ATTR_FORMAT(printf, 1, 2) ATTR_NORETURN; 423 424#endif /* _UTIL_H_ */ 425