Developer Area

root/tools/iphone-sdk/trunk/ldns_sources/util.c @ 81

Revision 32, 6.1 kB (checked in by kjaleel, 6 years ago)

unzipped the DotTel?.zip and moved it into trunk

Line 
1/*
2 * util.c
3 *
4 * some general memory functions
5 *
6 * a Net::DNS like library for C
7 *
8 * (c) NLnet Labs, 2004-2006
9 *
10 * See the file LICENSE for the license
11 */
12
13#include "ldns/config.h"
14
15#include "ldns/rdata.h"
16#include "ldns/rr.h"
17#include "ldns/util.h"
18#include <strings.h>
19#include <stdlib.h>
20#include <stdio.h>
21#include <sys/time.h>
22#include <time.h>
23
24#ifdef HAVE_SSL
25#include <openssl/rand.h>
26#endif
27
28/* put this here tmp. for debugging */
29void
30xprintf_rdf(ldns_rdf *rd)
31{
32        /* assume printable string */
33        fprintf(stderr, "size\t:%u\n", (unsigned int)ldns_rdf_size(rd));
34        fprintf(stderr, "type\t:%u\n", (unsigned int)ldns_rdf_get_type(rd));
35        fprintf(stderr, "data\t:[%.*s]\n", (int)ldns_rdf_size(rd), 
36                        (char*)ldns_rdf_data(rd));
37}
38
39void
40xprintf_rr(ldns_rr *rr)
41{
42        /* assume printable string */
43        uint16_t count, i;
44
45        count = ldns_rr_rd_count(rr);
46
47        for(i = 0; i < count; i++) {
48                fprintf(stderr, "print rd %u\n", (unsigned int) i);
49                xprintf_rdf(rr->_rdata_fields[i]);
50        }
51}
52
53void xprintf_hex(uint8_t *data, size_t len)
54{
55        size_t i;
56        for (i = 0; i < len; i++) {
57                if (i > 0 && i % 20 == 0) {
58                        printf("\t; %u - %u\n", (unsigned int) i - 19, (unsigned int) i);
59                }
60                printf("%02x ", (unsigned int) data[i]);
61        }
62        printf("\n");
63}
64
65ldns_lookup_table *
66ldns_lookup_by_name(ldns_lookup_table *table, const char *name)
67{
68        while (table->name != NULL) {
69                if (strcasecmp(name, table->name) == 0)
70                        return table;
71                table++;
72        }
73        return NULL;
74}
75
76ldns_lookup_table *
77ldns_lookup_by_id(ldns_lookup_table *table, int id)
78{
79        while (table->name != NULL) {
80                if (table->id == id)
81                        return table;
82                table++;
83        }
84        return NULL;
85}
86
87int 
88ldns_get_bit(uint8_t bits[], size_t index)
89{
90        /*
91         * The bits are counted from left to right, so bit #0 is the
92         * left most bit.
93         */
94        return (int) (bits[index / 8] & (1 << (7 - index % 8)));
95}
96
97int 
98ldns_get_bit_r(uint8_t bits[], size_t index)
99{
100        /*
101         * The bits are counted from right to left, so bit #0 is the
102         * right most bit.
103         */
104        return (int) bits[index / 8] & (1 << (index % 8));
105}
106
107void
108ldns_set_bit(uint8_t *byte, int bit_nr, bool value) 
109{
110        if (bit_nr >= 0 && bit_nr < 8) {
111                if (value) {
112                        *byte = *byte | (0x01 << bit_nr);
113                } else {
114                        *byte = *byte & !(0x01 << bit_nr);
115                }
116        }
117}
118
119int
120ldns_hexdigit_to_int(char ch)
121{
122        switch (ch) {
123        case '0': return 0;
124        case '1': return 1;
125        case '2': return 2;
126        case '3': return 3;
127        case '4': return 4;
128        case '5': return 5;
129        case '6': return 6;
130        case '7': return 7;
131        case '8': return 8;
132        case '9': return 9;
133        case 'a': case 'A': return 10;
134        case 'b': case 'B': return 11;
135        case 'c': case 'C': return 12;
136        case 'd': case 'D': return 13;
137        case 'e': case 'E': return 14;
138        case 'f': case 'F': return 15;
139        default:
140                return -1;
141        }
142}
143
144char 
145ldns_int_to_hexdigit(int i)
146{
147        switch (i) {
148        case 0: return '0';
149        case 1: return '1';
150        case 2: return '2';
151        case 3: return '3';
152        case 4: return '4';
153        case 5: return '5';
154        case 6: return '6';
155        case 7: return '7';
156        case 8: return '8';
157        case 9: return '9';
158        case 10: return 'a';
159        case 11: return 'b';
160        case 12: return 'c';
161        case 13: return 'd';
162        case 14: return 'e';
163        case 15: return 'f';
164        default:
165                abort();
166        }
167}
168
169int
170ldns_hexstring_to_data(uint8_t *data, const char *str)
171{
172        unsigned int i;
173
174        if (!str || !data) {
175                return -1;
176        }
177
178        if (strlen(str) % 2 != 0) {
179                return -2;
180        }
181
182        for (i = 0; i < strlen(str) / 2; i++) {
183                data[i] = 
184                        16 *    ldns_hexdigit_to_int(str[i*2]) +
185                        ldns_hexdigit_to_int(str[i*2 + 1]);
186        }
187
188        return (int) i;
189}
190
191const char *
192ldns_version(void)
193{
194        return (char*)LDNS_VERSION;
195}
196
197/* Number of days per month (except for February in leap years). */
198static const int mdays[] = {
199        31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
200};
201
202static int 
203is_leap_year(int year)
204{
205        return year % 4 == 0 && (year % 100 != 0 || year % 400 == 0);
206}
207
208static int
209leap_days(int y1, int y2)
210{
211        --y1;
212        --y2;
213        return (y2/4 - y1/4) - (y2/100 - y1/100) + (y2/400 - y1/400);
214}
215
216/*
217 * Code adapted from Python 2.4.1 sources (Lib/calendar.py).
218 */
219time_t
220mktime_from_utc(const struct tm *tm)
221{
222        int year = 1900 + tm->tm_year;
223        time_t days = 365 * ((time_t) year - 1970) + leap_days(1970, year);
224        time_t hours;
225        time_t minutes;
226        time_t seconds;
227        int i;
228
229        for (i = 0; i < tm->tm_mon; ++i) {
230                days += mdays[i];
231        }
232        if (tm->tm_mon > 1 && is_leap_year(year)) {
233                ++days;
234        }
235        days += tm->tm_mday - 1;
236
237        hours = days * 24 + tm->tm_hour;
238        minutes = hours * 60 + tm->tm_min;
239        seconds = minutes * 60 + tm->tm_sec;
240
241        return seconds;
242}
243
244/**
245 * Init the random source
246 * applications should call this if they need entropy data within ldns
247 * If openSSL is available, it is automatically seeded from /dev/urandom
248 * or /dev/random
249 *
250 * If you need more entropy, or have no openssl available, this function
251 * MUST be called at the start of the program
252 *
253 * If openssl *is* available, this function just adds more entropy
254 **/
255int
256ldns_init_random(FILE *fd, unsigned int size) 
257{
258        /* if fp is given, seed srandom with data from file
259           otherwise use /dev/urandom */
260        FILE *rand_f;
261        unsigned int *seed;
262        size_t read = 0;
263        unsigned int seed_i;
264        struct timeval tv;
265        struct timezone tz;
266
267        /* we'll need at least sizeof(unsigned int) bytes for the
268           standard prng seed */
269        if (size < sizeof(seed_i)){
270                size = sizeof(seed_i);
271        }
272       
273        seed = LDNS_XMALLOC(unsigned int, size);
274
275        if (!fd) {
276                if ((rand_f = fopen("/dev/urandom", "r")) == NULL) {
277                        /* no readable /dev/urandom, try /dev/random */
278                        if ((rand_f = fopen("/dev/random", "r")) == NULL) {
279                                /* no readable /dev/random either, and no entropy
280                                   source given. we'll have to improvise */
281                                for (read = 0; read < size; read++) {
282                                        gettimeofday(&tv, &tz);
283                                        seed[read] = (uint8_t) (tv.tv_usec % 256);
284                                }
285                        }
286                }
287        } else {
288                rand_f = fd;
289                read = fread(seed, 1, size, rand_f);
290        }
291       
292        if (read < size) {
293                LDNS_FREE(seed);
294                return 1;
295        } else {
296#ifdef HAVE_SSL
297                /* Seed the OpenSSL prng (most systems have it seeded
298                   automatically, in that case this call just adds entropy */
299                RAND_seed(seed, size);
300#else
301                /* Seed the standard prng, only uses the first
302                 * unsigned sizeof(unsiged int) bytes found in the entropy pool
303                 */
304                memcpy(&seed_i, seed, sizeof(seed_i));
305                srandom(seed_i);
306#endif
307                LDNS_FREE(seed);
308        }
309       
310        if (!fd) {
311                fclose(rand_f);
312        }
313
314        return 0;
315}
Note: See TracBrowser for help on using the browser.
Telnic
Search This Site
Partners
Neustar
ICANN
Main site | WHOIS | Sell .tel | FAQ | Archived Site | About Telnic | Contact Us