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