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