File Coverage

include/ldns/util.h
Criterion Covered Total %
statement 4 26 15.3
branch 1 8 12.5
condition n/a
subroutine n/a
pod n/a
total 5 34 14.7


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