| Commit | Line | Data |
|---|---|---|
| df278fc2 JL |
1 | /* |
| 2 | * util.h | |
| 3 | * | |
| 4 | * helper function header file | |
| 5 | * | |
| 6 | * a Net::DNS like library for C | |
| 7 | * | |
| 8 | * (c) NLnet Labs, 2004 | |
| 9 | * | |
| 10 | * See the file LICENSE for the license | |
| 11 | */ | |
| 12 | ||
| 13 | #ifndef _UTIL_H | |
| 14 | #define _UTIL_H | |
| 15 | ||
| 16 | #include <inttypes.h> | |
| fcd4e566 JL |
17 | #include <sys/types.h> |
| 18 | #include <unistd.h> | |
| df278fc2 JL |
19 | #include <ldns/common.h> |
| 20 | #include <time.h> | |
| 21 | #include <stdio.h> | |
| 22 | ||
| fcd4e566 JL |
23 | #ifdef __cplusplus |
| 24 | extern "C" { | |
| 25 | #endif | |
| 26 | ||
| df278fc2 JL |
27 | #define dprintf(X,Y) fprintf(stderr, (X), (Y)) |
| 28 | /* #define dprintf(X, Y) */ | |
| 29 | ||
| de9b0015 JL |
30 | #define LDNS_VERSION "1.6.11" |
| 31 | #define LDNS_REVISION ((1<<16)|(6<<8)|(11)) | |
| df278fc2 JL |
32 | |
| 33 | /** | |
| 34 | * splint static inline workaround | |
| 35 | */ | |
| 36 | #ifdef S_SPLINT_S | |
| 37 | # define INLINE | |
| 38 | #else | |
| 39 | # ifdef SWIG | |
| 40 | # define INLINE static | |
| 41 | # else | |
| 42 | # define INLINE static inline | |
| 43 | # endif | |
| 44 | #endif | |
| 45 | ||
| 46 | /** | |
| 47 | * Memory management macros | |
| 48 | */ | |
| 49 | #define LDNS_MALLOC(type) LDNS_XMALLOC(type, 1) | |
| 50 | ||
| 51 | #define LDNS_XMALLOC(type, count) ((type *) malloc((count) * sizeof(type))) | |
| 52 | ||
| de9b0015 JL |
53 | #define LDNS_CALLOC(type, count) ((type *) calloc((count), sizeof(type))) |
| 54 | ||
| df278fc2 JL |
55 | #define LDNS_REALLOC(ptr, type) LDNS_XREALLOC((ptr), type, 1) |
| 56 | ||
| 57 | #define LDNS_XREALLOC(ptr, type, count) \ | |
| 58 | ((type *) realloc((ptr), (count) * sizeof(type))) | |
| 59 | ||
| 60 | #define LDNS_FREE(ptr) \ | |
| 61 | do { free((ptr)); (ptr) = NULL; } while (0) | |
| 62 | ||
| 63 | #define LDNS_DEP printf("DEPRECATED FUNCTION!\n"); | |
| 64 | ||
| 65 | /* | |
| 66 | * Copy data allowing for unaligned accesses in network byte order | |
| 67 | * (big endian). | |
| 68 | */ | |
| 69 | INLINE uint16_t | |
| 70 | ldns_read_uint16(const void *src) | |
| 71 | { | |
| 72 | #ifdef ALLOW_UNALIGNED_ACCESSES | |
| 73 | return ntohs(*(uint16_t *) src); | |
| 74 | #else | |
| 75 | uint8_t *p = (uint8_t *) src; | |
| 76 | return ((uint16_t) p[0] << 8) | (uint16_t) p[1]; | |
| 77 | #endif | |
| 78 | } | |
| 79 | ||
| 80 | INLINE uint32_t | |
| 81 | ldns_read_uint32(const void *src) | |
| 82 | { | |
| 83 | #ifdef ALLOW_UNALIGNED_ACCESSES | |
| 84 | return ntohl(*(uint32_t *) src); | |
| 85 | #else | |
| 86 | uint8_t *p = (uint8_t *) src; | |
| 87 | return ( ((uint32_t) p[0] << 24) | |
| 88 | | ((uint32_t) p[1] << 16) | |
| 89 | | ((uint32_t) p[2] << 8) | |
| 90 | | (uint32_t) p[3]); | |
| 91 | #endif | |
| 92 | } | |
| 93 | ||
| 94 | /* | |
| 95 | * Copy data allowing for unaligned accesses in network byte order | |
| 96 | * (big endian). | |
| 97 | */ | |
| 98 | INLINE void | |
| 99 | ldns_write_uint16(void *dst, uint16_t data) | |
| 100 | { | |
| 101 | #ifdef ALLOW_UNALIGNED_ACCESSES | |
| 102 | * (uint16_t *) dst = htons(data); | |
| 103 | #else | |
| 104 | uint8_t *p = (uint8_t *) dst; | |
| 105 | p[0] = (uint8_t) ((data >> 8) & 0xff); | |
| 106 | p[1] = (uint8_t) (data & 0xff); | |
| 107 | #endif | |
| 108 | } | |
| 109 | ||
| 110 | INLINE void | |
| 111 | ldns_write_uint32(void *dst, uint32_t data) | |
| 112 | { | |
| 113 | #ifdef ALLOW_UNALIGNED_ACCESSES | |
| 114 | * (uint32_t *) dst = htonl(data); | |
| 115 | #else | |
| 116 | uint8_t *p = (uint8_t *) dst; | |
| 117 | p[0] = (uint8_t) ((data >> 24) & 0xff); | |
| 118 | p[1] = (uint8_t) ((data >> 16) & 0xff); | |
| 119 | p[2] = (uint8_t) ((data >> 8) & 0xff); | |
| 120 | p[3] = (uint8_t) (data & 0xff); | |
| 121 | #endif | |
| 122 | } | |
| 123 | ||
| 124 | /* warning. */ | |
| 125 | INLINE void | |
| 126 | ldns_write_uint64_as_uint48(void *dst, uint64_t data) | |
| 127 | { | |
| 128 | uint8_t *p = (uint8_t *) dst; | |
| 129 | p[0] = (uint8_t) ((data >> 40) & 0xff); | |
| 130 | p[1] = (uint8_t) ((data >> 32) & 0xff); | |
| 131 | p[2] = (uint8_t) ((data >> 24) & 0xff); | |
| 132 | p[3] = (uint8_t) ((data >> 16) & 0xff); | |
| 133 | p[4] = (uint8_t) ((data >> 8) & 0xff); | |
| 134 | p[5] = (uint8_t) (data & 0xff); | |
| 135 | } | |
| 136 | ||
| 137 | ||
| 138 | /** | |
| 139 | * Structure to do a Schwartzian-like transformation, for instance when | |
| 140 | * sorting. If you need a transformation on the objects that are sorted, | |
| 141 | * you can sue this to store the transformed values, so you do not | |
| 142 | * need to do the transformation again for each comparison | |
| 143 | */ | |
| 144 | struct ldns_schwartzian_compare_struct { | |
| 145 | void *original_object; | |
| 146 | void *transformed_object; | |
| 147 | }; | |
| 148 | ||
| 149 | /** A general purpose lookup table | |
| 150 | * | |
| 151 | * Lookup tables are arrays of (id, name) pairs, | |
| 152 | * So you can for instance lookup the RCODE 3, which is "NXDOMAIN", | |
| 153 | * and vice versa. The lookup tables themselves are defined wherever needed, | |
| 154 | * for instance in \ref host2str.c | |
| 155 | */ | |
| 156 | struct ldns_struct_lookup_table { | |
| 157 | int id; | |
| 158 | const char *name; | |
| 159 | }; | |
| 160 | typedef struct ldns_struct_lookup_table ldns_lookup_table; | |
| 161 | ||
| 162 | /** | |
| 163 | * Looks up the table entry by name, returns NULL if not found. | |
| 164 | * \param[in] table the lookup table to search in | |
| 165 | * \param[in] name what to search for | |
| 166 | * \return the item found | |
| 167 | */ | |
| 168 | ldns_lookup_table *ldns_lookup_by_name(ldns_lookup_table table[], | |
| 169 | const char *name); | |
| 170 | ||
| 171 | /** | |
| 172 | * Looks up the table entry by id, returns NULL if not found. | |
| 173 | * \param[in] table the lookup table to search in | |
| 174 | * \param[in] id what to search for | |
| 175 | * \return the item found | |
| 176 | */ | |
| 177 | ldns_lookup_table *ldns_lookup_by_id(ldns_lookup_table table[], int id); | |
| 178 | ||
| 179 | /** | |
| 180 | * Returns the value of the specified bit | |
| 181 | * The bits are counted from left to right, so bit #0 is the | |
| 182 | * left most bit. | |
| 183 | * \param[in] bits array holding the bits | |
| 184 | * \param[in] index to the wanted bit | |
| 185 | * \return | |
| 186 | */ | |
| 187 | int ldns_get_bit(uint8_t bits[], size_t index); | |
| 188 | ||
| 189 | ||
| 190 | /** | |
| 191 | * Returns the value of the specified bit | |
| 192 | * The bits are counted from right to left, so bit #0 is the | |
| 193 | * right most bit. | |
| 194 | * \param[in] bits array holding the bits | |
| 195 | * \param[in] index to the wanted bit | |
| 196 | * \return 1 or 0 depending no the bit state | |
| 197 | */ | |
| 198 | int ldns_get_bit_r(uint8_t bits[], size_t index); | |
| 199 | ||
| 200 | /** | |
| 201 | * sets the specified bit in the specified byte to | |
| 202 | * 1 if value is true, 0 if false | |
| 203 | * The bits are counted from right to left, so bit #0 is the | |
| 204 | * right most bit. | |
| 205 | * \param[in] byte the bit to set the bit in | |
| 206 | * \param[in] bit_nr the bit to set (0 <= n <= 7) | |
| 207 | * \param[in] value whether to set the bit to 1 or 0 | |
| 208 | * \return 1 or 0 depending no the bit state | |
| 209 | */ | |
| 210 | void ldns_set_bit(uint8_t *byte, int bit_nr, bool value); | |
| 211 | ||
| 212 | /** | |
| 213 | * Returns the value of a to the power of b | |
| 214 | * (or 1 of b < 1) | |
| 215 | */ | |
| 216 | /*@unused@*/ | |
| 217 | INLINE long | |
| 218 | ldns_power(long a, long b) { | |
| 219 | long result = 1; | |
| 220 | while (b > 0) { | |
| 221 | if (b & 1) { | |
| 222 | result *= a; | |
| 223 | if (b == 1) { | |
| 224 | return result; | |
| 225 | } | |
| 226 | } | |
| 227 | a *= a; | |
| 228 | b /= 2; | |
| 229 | } | |
| 230 | return result; | |
| 231 | } | |
| 232 | ||
| 233 | /** | |
| 234 | * Returns the int value of the given (hex) digit | |
| 235 | * \param[in] ch the hex char to convert | |
| 236 | * \return the converted decimal value | |
| 237 | */ | |
| 238 | int ldns_hexdigit_to_int(char ch); | |
| 239 | ||
| 240 | /** | |
| 241 | * Returns the char (hex) representation of the given int | |
| 242 | * \param[in] ch the int to convert | |
| 243 | * \return the converted hex char | |
| 244 | */ | |
| 245 | char ldns_int_to_hexdigit(int ch); | |
| 246 | ||
| 247 | /** | |
| 248 | * Converts a hex string to binary data | |
| 249 | * | |
| 250 | * \param[out] data The binary result is placed here. | |
| 251 | * At least strlen(str)/2 bytes should be allocated | |
| 252 | * \param[in] str The hex string to convert. | |
| 253 | * This string should not contain spaces | |
| 254 | * \return The number of bytes of converted data, or -1 if one of the arguments * is NULL, or -2 if the string length is not an even number | |
| 255 | */ | |
| 256 | int | |
| 257 | ldns_hexstring_to_data(uint8_t *data, const char *str); | |
| 258 | ||
| 259 | /** | |
| 260 | * Show the internal library version | |
| 261 | * \return a string with the version in it | |
| 262 | */ | |
| 263 | const char * ldns_version(void); | |
| 264 | ||
| 265 | /** | |
| 266 | * Convert TM to seconds since epoch (midnight, January 1st, 1970). | |
| 267 | * Like timegm(3), which is not always available. | |
| 268 | * \param[in] tm a struct tm* with the date | |
| 269 | * \return the seconds since epoch | |
| 270 | */ | |
| 271 | time_t mktime_from_utc(const struct tm *tm); | |
| 272 | ||
| 273 | /** | |
| de9b0015 JL |
274 | * The function interprets time as the number of seconds since epoch |
| 275 | * with respect to now using serial arithmitics (rfc1982). | |
| 276 | * That number of seconds is then converted to broken-out time information. | |
| 277 | * This is especially usefull when converting the inception and expiration | |
| 278 | * fields of RRSIG records. | |
| 279 | * | |
| 280 | * \param[in] time number of seconds since epoch (midnight, January 1st, 1970) | |
| 281 | * to be intepreted as a serial arithmitics number relative to now. | |
| 282 | * \param[in] now number of seconds since epoch (midnight, January 1st, 1970) | |
| 283 | * to which the time value is compared to determine the final value. | |
| 284 | * \param[out] result the struct with the broken-out time information | |
| 285 | * \return result on success or NULL on error | |
| 286 | */ | |
| 287 | struct tm * ldns_serial_arithmitics_gmtime_r(int32_t time, time_t now, struct tm *result); | |
| 288 | ||
| 289 | /** | |
| df278fc2 JL |
290 | * Seed the random function. |
| 291 | * If the file descriptor is specified, the random generator is seeded with | |
| 292 | * data from that file. If not, /dev/urandom is used. | |
| 293 | * | |
| 294 | * applications should call this if they need entropy data within ldns | |
| 295 | * If openSSL is available, it is automatically seeded from /dev/urandom | |
| 296 | * or /dev/random. | |
| 297 | * | |
| 298 | * If you need more entropy, or have no openssl available, this function | |
| 299 | * MUST be called at the start of the program | |
| 300 | * | |
| 301 | * If openssl *is* available, this function just adds more entropy | |
| 302 | * | |
| 303 | * \param[in] fd a file providing entropy data for the seed | |
| 304 | * \param[in] size the number of bytes to use as entropy data. If this is 0, | |
| 305 | * only the minimal amount is taken (usually 4 bytes) | |
| 306 | * \return 0 if seeding succeeds, 1 if it fails | |
| 307 | */ | |
| 308 | int ldns_init_random(FILE *fd, unsigned int size); | |
| 309 | ||
| fcd4e566 JL |
310 | /** |
| 311 | * Get random number. | |
| 312 | * \return random number. | |
| 313 | * | |
| 314 | */ | |
| 315 | uint16_t ldns_get_random(void); | |
| df278fc2 JL |
316 | |
| 317 | /** | |
| 318 | * Encode data as BubbleBabble | |
| 319 | * | |
| 320 | * \param[in] data a pointer to data to be encoded | |
| 321 | * \param[in] len size the number of bytes of data | |
| 322 | * \return a string of BubbleBabble | |
| 323 | */ | |
| 324 | char *ldns_bubblebabble(uint8_t *data, size_t len); | |
| 325 | ||
| 326 | #ifndef B32_NTOP | |
| 327 | int ldns_b32_ntop(uint8_t const *src, size_t srclength, | |
| 328 | char *target, size_t targsize); | |
| 329 | int b32_ntop(uint8_t const *src, size_t srclength, | |
| 330 | char *target, size_t targsize); | |
| 331 | int ldns_b32_ntop_extended_hex(uint8_t const *src, size_t srclength, | |
| 332 | char *target, size_t targsize); | |
| 333 | int b32_ntop_extended_hex(uint8_t const *src, size_t srclength, | |
| 334 | char *target, size_t targsize); | |
| 335 | /** | |
| 336 | * calculates the size needed to store the result of b32_ntop | |
| 337 | */ | |
| 338 | /*@unused@*/ | |
| 339 | INLINE size_t ldns_b32_ntop_calculate_size(size_t srcsize) | |
| 340 | { | |
| 341 | size_t result = ((((srcsize / 5) * 8) - 2) + 2); | |
| 342 | return result; | |
| 343 | } | |
| 344 | #endif /* !B32_NTOP */ | |
| 345 | #ifndef B32_PTON | |
| 346 | int ldns_b32_pton(char const *src, size_t hashed_owner_str_len, uint8_t *target, size_t targsize); | |
| 347 | int b32_pton(char const *src, size_t hashed_owner_str_len, uint8_t *target, size_t targsize); | |
| 348 | int ldns_b32_pton_extended_hex(char const *src, size_t hashed_owner_str_len, uint8_t *target, size_t targsize); | |
| 349 | int b32_pton_extended_hex(char const *src, size_t hashed_owner_str_len, uint8_t *target, size_t targsize); | |
| 350 | /** | |
| 351 | * calculates the size needed to store the result of b32_pton | |
| 352 | */ | |
| 353 | /*@unused@*/ | |
| 354 | INLINE size_t ldns_b32_pton_calculate_size(size_t srcsize) | |
| 355 | { | |
| 356 | size_t result = ((((srcsize) / 8) * 5)); | |
| 357 | return result; | |
| 358 | } | |
| 359 | #endif /* !B32_PTON */ | |
| 360 | ||
| fcd4e566 JL |
361 | #ifdef __cplusplus |
| 362 | } | |
| 363 | #endif | |
| 364 | ||
| df278fc2 | 365 | #endif /* !_UTIL_H */ |