2
0

util.h 8.6 KB

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