xref: /freebsd/contrib/ldns/rdata.c (revision 7b5038d71c5c74ab863c1ff3fec33de94bf35a57)
1*7b5038d7SDag-Erling Smørgrav /*
2*7b5038d7SDag-Erling Smørgrav  * rdata.c
3*7b5038d7SDag-Erling Smørgrav  *
4*7b5038d7SDag-Erling Smørgrav  * rdata implementation
5*7b5038d7SDag-Erling Smørgrav  *
6*7b5038d7SDag-Erling Smørgrav  * a Net::DNS like library for C
7*7b5038d7SDag-Erling Smørgrav  *
8*7b5038d7SDag-Erling Smørgrav  * (c) NLnet Labs, 2004-2006
9*7b5038d7SDag-Erling Smørgrav  *
10*7b5038d7SDag-Erling Smørgrav  * See the file LICENSE for the license
11*7b5038d7SDag-Erling Smørgrav  */
12*7b5038d7SDag-Erling Smørgrav 
13*7b5038d7SDag-Erling Smørgrav #include <ldns/config.h>
14*7b5038d7SDag-Erling Smørgrav 
15*7b5038d7SDag-Erling Smørgrav #include <ldns/ldns.h>
16*7b5038d7SDag-Erling Smørgrav 
17*7b5038d7SDag-Erling Smørgrav /*
18*7b5038d7SDag-Erling Smørgrav  * Access functions
19*7b5038d7SDag-Erling Smørgrav  * do this as functions to get type checking
20*7b5038d7SDag-Erling Smørgrav  */
21*7b5038d7SDag-Erling Smørgrav 
22*7b5038d7SDag-Erling Smørgrav /* read */
23*7b5038d7SDag-Erling Smørgrav size_t
24*7b5038d7SDag-Erling Smørgrav ldns_rdf_size(const ldns_rdf *rd)
25*7b5038d7SDag-Erling Smørgrav {
26*7b5038d7SDag-Erling Smørgrav 	assert(rd != NULL);
27*7b5038d7SDag-Erling Smørgrav 	return rd->_size;
28*7b5038d7SDag-Erling Smørgrav }
29*7b5038d7SDag-Erling Smørgrav 
30*7b5038d7SDag-Erling Smørgrav ldns_rdf_type
31*7b5038d7SDag-Erling Smørgrav ldns_rdf_get_type(const ldns_rdf *rd)
32*7b5038d7SDag-Erling Smørgrav {
33*7b5038d7SDag-Erling Smørgrav 	assert(rd != NULL);
34*7b5038d7SDag-Erling Smørgrav 	return rd->_type;
35*7b5038d7SDag-Erling Smørgrav }
36*7b5038d7SDag-Erling Smørgrav 
37*7b5038d7SDag-Erling Smørgrav uint8_t *
38*7b5038d7SDag-Erling Smørgrav ldns_rdf_data(const ldns_rdf *rd)
39*7b5038d7SDag-Erling Smørgrav {
40*7b5038d7SDag-Erling Smørgrav 	assert(rd != NULL);
41*7b5038d7SDag-Erling Smørgrav 	return rd->_data;
42*7b5038d7SDag-Erling Smørgrav }
43*7b5038d7SDag-Erling Smørgrav 
44*7b5038d7SDag-Erling Smørgrav /* write */
45*7b5038d7SDag-Erling Smørgrav void
46*7b5038d7SDag-Erling Smørgrav ldns_rdf_set_size(ldns_rdf *rd, size_t size)
47*7b5038d7SDag-Erling Smørgrav {
48*7b5038d7SDag-Erling Smørgrav 	assert(rd != NULL);
49*7b5038d7SDag-Erling Smørgrav 	rd->_size = size;
50*7b5038d7SDag-Erling Smørgrav }
51*7b5038d7SDag-Erling Smørgrav 
52*7b5038d7SDag-Erling Smørgrav void
53*7b5038d7SDag-Erling Smørgrav ldns_rdf_set_type(ldns_rdf *rd, ldns_rdf_type type)
54*7b5038d7SDag-Erling Smørgrav {
55*7b5038d7SDag-Erling Smørgrav 	assert(rd != NULL);
56*7b5038d7SDag-Erling Smørgrav 	rd->_type = type;
57*7b5038d7SDag-Erling Smørgrav }
58*7b5038d7SDag-Erling Smørgrav 
59*7b5038d7SDag-Erling Smørgrav void
60*7b5038d7SDag-Erling Smørgrav ldns_rdf_set_data(ldns_rdf *rd, void *data)
61*7b5038d7SDag-Erling Smørgrav {
62*7b5038d7SDag-Erling Smørgrav 	/* only copy the pointer */
63*7b5038d7SDag-Erling Smørgrav 	assert(rd != NULL);
64*7b5038d7SDag-Erling Smørgrav 	rd->_data = data;
65*7b5038d7SDag-Erling Smørgrav }
66*7b5038d7SDag-Erling Smørgrav 
67*7b5038d7SDag-Erling Smørgrav /* for types that allow it, return
68*7b5038d7SDag-Erling Smørgrav  * the native/host order type */
69*7b5038d7SDag-Erling Smørgrav uint8_t
70*7b5038d7SDag-Erling Smørgrav ldns_rdf2native_int8(const ldns_rdf *rd)
71*7b5038d7SDag-Erling Smørgrav {
72*7b5038d7SDag-Erling Smørgrav 	uint8_t data;
73*7b5038d7SDag-Erling Smørgrav 
74*7b5038d7SDag-Erling Smørgrav 	/* only allow 8 bit rdfs */
75*7b5038d7SDag-Erling Smørgrav 	if (ldns_rdf_size(rd) != LDNS_RDF_SIZE_BYTE) {
76*7b5038d7SDag-Erling Smørgrav 		return 0;
77*7b5038d7SDag-Erling Smørgrav 	}
78*7b5038d7SDag-Erling Smørgrav 
79*7b5038d7SDag-Erling Smørgrav 	memcpy(&data, ldns_rdf_data(rd), sizeof(data));
80*7b5038d7SDag-Erling Smørgrav 	return data;
81*7b5038d7SDag-Erling Smørgrav }
82*7b5038d7SDag-Erling Smørgrav 
83*7b5038d7SDag-Erling Smørgrav uint16_t
84*7b5038d7SDag-Erling Smørgrav ldns_rdf2native_int16(const ldns_rdf *rd)
85*7b5038d7SDag-Erling Smørgrav {
86*7b5038d7SDag-Erling Smørgrav 	uint16_t data;
87*7b5038d7SDag-Erling Smørgrav 
88*7b5038d7SDag-Erling Smørgrav 	/* only allow 16 bit rdfs */
89*7b5038d7SDag-Erling Smørgrav 	if (ldns_rdf_size(rd) != LDNS_RDF_SIZE_WORD) {
90*7b5038d7SDag-Erling Smørgrav 		return 0;
91*7b5038d7SDag-Erling Smørgrav 	}
92*7b5038d7SDag-Erling Smørgrav 
93*7b5038d7SDag-Erling Smørgrav 	memcpy(&data, ldns_rdf_data(rd), sizeof(data));
94*7b5038d7SDag-Erling Smørgrav 	return ntohs(data);
95*7b5038d7SDag-Erling Smørgrav }
96*7b5038d7SDag-Erling Smørgrav 
97*7b5038d7SDag-Erling Smørgrav uint32_t
98*7b5038d7SDag-Erling Smørgrav ldns_rdf2native_int32(const ldns_rdf *rd)
99*7b5038d7SDag-Erling Smørgrav {
100*7b5038d7SDag-Erling Smørgrav 	uint32_t data;
101*7b5038d7SDag-Erling Smørgrav 
102*7b5038d7SDag-Erling Smørgrav 	/* only allow 32 bit rdfs */
103*7b5038d7SDag-Erling Smørgrav 	if (ldns_rdf_size(rd) != LDNS_RDF_SIZE_DOUBLEWORD) {
104*7b5038d7SDag-Erling Smørgrav 		return 0;
105*7b5038d7SDag-Erling Smørgrav 	}
106*7b5038d7SDag-Erling Smørgrav 
107*7b5038d7SDag-Erling Smørgrav 	memcpy(&data, ldns_rdf_data(rd), sizeof(data));
108*7b5038d7SDag-Erling Smørgrav 	return ntohl(data);
109*7b5038d7SDag-Erling Smørgrav }
110*7b5038d7SDag-Erling Smørgrav 
111*7b5038d7SDag-Erling Smørgrav time_t
112*7b5038d7SDag-Erling Smørgrav ldns_rdf2native_time_t(const ldns_rdf *rd)
113*7b5038d7SDag-Erling Smørgrav {
114*7b5038d7SDag-Erling Smørgrav 	uint32_t data;
115*7b5038d7SDag-Erling Smørgrav 
116*7b5038d7SDag-Erling Smørgrav 	switch(ldns_rdf_get_type(rd)) {
117*7b5038d7SDag-Erling Smørgrav 		case LDNS_RDF_TYPE_TIME:
118*7b5038d7SDag-Erling Smørgrav 			memcpy(&data, ldns_rdf_data(rd), sizeof(data));
119*7b5038d7SDag-Erling Smørgrav 			return (time_t)ntohl(data);
120*7b5038d7SDag-Erling Smørgrav 		default:
121*7b5038d7SDag-Erling Smørgrav 			return 0;
122*7b5038d7SDag-Erling Smørgrav 	}
123*7b5038d7SDag-Erling Smørgrav }
124*7b5038d7SDag-Erling Smørgrav 
125*7b5038d7SDag-Erling Smørgrav ldns_rdf *
126*7b5038d7SDag-Erling Smørgrav ldns_native2rdf_int8(ldns_rdf_type type, uint8_t value)
127*7b5038d7SDag-Erling Smørgrav {
128*7b5038d7SDag-Erling Smørgrav 	return ldns_rdf_new_frm_data(type, LDNS_RDF_SIZE_BYTE, &value);
129*7b5038d7SDag-Erling Smørgrav }
130*7b5038d7SDag-Erling Smørgrav 
131*7b5038d7SDag-Erling Smørgrav ldns_rdf *
132*7b5038d7SDag-Erling Smørgrav ldns_native2rdf_int16(ldns_rdf_type type, uint16_t value)
133*7b5038d7SDag-Erling Smørgrav {
134*7b5038d7SDag-Erling Smørgrav 	uint16_t *rdf_data = LDNS_XMALLOC(uint16_t, 1);
135*7b5038d7SDag-Erling Smørgrav         ldns_rdf* rdf;
136*7b5038d7SDag-Erling Smørgrav 	if (!rdf_data) {
137*7b5038d7SDag-Erling Smørgrav 		return NULL;
138*7b5038d7SDag-Erling Smørgrav 	}
139*7b5038d7SDag-Erling Smørgrav 	ldns_write_uint16(rdf_data, value);
140*7b5038d7SDag-Erling Smørgrav 	rdf = ldns_rdf_new(type, LDNS_RDF_SIZE_WORD, rdf_data);
141*7b5038d7SDag-Erling Smørgrav         if(!rdf)
142*7b5038d7SDag-Erling Smørgrav                 LDNS_FREE(rdf_data);
143*7b5038d7SDag-Erling Smørgrav         return rdf;
144*7b5038d7SDag-Erling Smørgrav }
145*7b5038d7SDag-Erling Smørgrav 
146*7b5038d7SDag-Erling Smørgrav ldns_rdf *
147*7b5038d7SDag-Erling Smørgrav ldns_native2rdf_int32(ldns_rdf_type type, uint32_t value)
148*7b5038d7SDag-Erling Smørgrav {
149*7b5038d7SDag-Erling Smørgrav 	uint32_t *rdf_data = LDNS_XMALLOC(uint32_t, 1);
150*7b5038d7SDag-Erling Smørgrav         ldns_rdf* rdf;
151*7b5038d7SDag-Erling Smørgrav 	if (!rdf_data) {
152*7b5038d7SDag-Erling Smørgrav 		return NULL;
153*7b5038d7SDag-Erling Smørgrav 	}
154*7b5038d7SDag-Erling Smørgrav 	ldns_write_uint32(rdf_data, value);
155*7b5038d7SDag-Erling Smørgrav 	rdf = ldns_rdf_new(type, LDNS_RDF_SIZE_DOUBLEWORD, rdf_data);
156*7b5038d7SDag-Erling Smørgrav         if(!rdf)
157*7b5038d7SDag-Erling Smørgrav                 LDNS_FREE(rdf_data);
158*7b5038d7SDag-Erling Smørgrav         return rdf;
159*7b5038d7SDag-Erling Smørgrav }
160*7b5038d7SDag-Erling Smørgrav 
161*7b5038d7SDag-Erling Smørgrav ldns_rdf *
162*7b5038d7SDag-Erling Smørgrav ldns_native2rdf_int16_data(size_t size, uint8_t *data)
163*7b5038d7SDag-Erling Smørgrav {
164*7b5038d7SDag-Erling Smørgrav 	uint8_t *rdf_data = LDNS_XMALLOC(uint8_t, size + 2);
165*7b5038d7SDag-Erling Smørgrav         ldns_rdf* rdf;
166*7b5038d7SDag-Erling Smørgrav 	if (!rdf_data) {
167*7b5038d7SDag-Erling Smørgrav 		return NULL;
168*7b5038d7SDag-Erling Smørgrav 	}
169*7b5038d7SDag-Erling Smørgrav 	ldns_write_uint16(rdf_data, size);
170*7b5038d7SDag-Erling Smørgrav 	memcpy(rdf_data + 2, data, size);
171*7b5038d7SDag-Erling Smørgrav 	rdf = ldns_rdf_new(LDNS_RDF_TYPE_INT16_DATA, size + 2, rdf_data);
172*7b5038d7SDag-Erling Smørgrav         if(!rdf)
173*7b5038d7SDag-Erling Smørgrav                 LDNS_FREE(rdf_data);
174*7b5038d7SDag-Erling Smørgrav         return rdf;
175*7b5038d7SDag-Erling Smørgrav }
176*7b5038d7SDag-Erling Smørgrav 
177*7b5038d7SDag-Erling Smørgrav /* note: data must be allocated memory */
178*7b5038d7SDag-Erling Smørgrav ldns_rdf *
179*7b5038d7SDag-Erling Smørgrav ldns_rdf_new(ldns_rdf_type type, size_t size, void *data)
180*7b5038d7SDag-Erling Smørgrav {
181*7b5038d7SDag-Erling Smørgrav 	ldns_rdf *rd;
182*7b5038d7SDag-Erling Smørgrav 	rd = LDNS_MALLOC(ldns_rdf);
183*7b5038d7SDag-Erling Smørgrav 	if (!rd) {
184*7b5038d7SDag-Erling Smørgrav 		return NULL;
185*7b5038d7SDag-Erling Smørgrav 	}
186*7b5038d7SDag-Erling Smørgrav 	ldns_rdf_set_size(rd, size);
187*7b5038d7SDag-Erling Smørgrav 	ldns_rdf_set_type(rd, type);
188*7b5038d7SDag-Erling Smørgrav 	ldns_rdf_set_data(rd, data);
189*7b5038d7SDag-Erling Smørgrav 	return rd;
190*7b5038d7SDag-Erling Smørgrav }
191*7b5038d7SDag-Erling Smørgrav 
192*7b5038d7SDag-Erling Smørgrav ldns_rdf *
193*7b5038d7SDag-Erling Smørgrav ldns_rdf_new_frm_data(ldns_rdf_type type, size_t size, const void *data)
194*7b5038d7SDag-Erling Smørgrav {
195*7b5038d7SDag-Erling Smørgrav 	ldns_rdf *rdf;
196*7b5038d7SDag-Erling Smørgrav 
197*7b5038d7SDag-Erling Smørgrav 	/* if the size is too big, fail */
198*7b5038d7SDag-Erling Smørgrav 	if (size > LDNS_MAX_RDFLEN) {
199*7b5038d7SDag-Erling Smørgrav 		return NULL;
200*7b5038d7SDag-Erling Smørgrav 	}
201*7b5038d7SDag-Erling Smørgrav 
202*7b5038d7SDag-Erling Smørgrav 	/* allocate space */
203*7b5038d7SDag-Erling Smørgrav 	rdf = LDNS_MALLOC(ldns_rdf);
204*7b5038d7SDag-Erling Smørgrav 	if (!rdf) {
205*7b5038d7SDag-Erling Smørgrav 		return NULL;
206*7b5038d7SDag-Erling Smørgrav 	}
207*7b5038d7SDag-Erling Smørgrav 	rdf->_data = LDNS_XMALLOC(uint8_t, size);
208*7b5038d7SDag-Erling Smørgrav 	if (!rdf->_data) {
209*7b5038d7SDag-Erling Smørgrav 		LDNS_FREE(rdf);
210*7b5038d7SDag-Erling Smørgrav 		return NULL;
211*7b5038d7SDag-Erling Smørgrav 	}
212*7b5038d7SDag-Erling Smørgrav 
213*7b5038d7SDag-Erling Smørgrav 	/* set the values */
214*7b5038d7SDag-Erling Smørgrav 	ldns_rdf_set_type(rdf, type);
215*7b5038d7SDag-Erling Smørgrav 	ldns_rdf_set_size(rdf, size);
216*7b5038d7SDag-Erling Smørgrav 	memcpy(rdf->_data, data, size);
217*7b5038d7SDag-Erling Smørgrav 
218*7b5038d7SDag-Erling Smørgrav 	return rdf;
219*7b5038d7SDag-Erling Smørgrav }
220*7b5038d7SDag-Erling Smørgrav 
221*7b5038d7SDag-Erling Smørgrav ldns_rdf *
222*7b5038d7SDag-Erling Smørgrav ldns_rdf_clone(const ldns_rdf *rd)
223*7b5038d7SDag-Erling Smørgrav {
224*7b5038d7SDag-Erling Smørgrav 	assert(rd != NULL);
225*7b5038d7SDag-Erling Smørgrav 	return (ldns_rdf_new_frm_data( ldns_rdf_get_type(rd),
226*7b5038d7SDag-Erling Smørgrav 		ldns_rdf_size(rd), ldns_rdf_data(rd)));
227*7b5038d7SDag-Erling Smørgrav }
228*7b5038d7SDag-Erling Smørgrav 
229*7b5038d7SDag-Erling Smørgrav void
230*7b5038d7SDag-Erling Smørgrav ldns_rdf_deep_free(ldns_rdf *rd)
231*7b5038d7SDag-Erling Smørgrav {
232*7b5038d7SDag-Erling Smørgrav 	if (rd) {
233*7b5038d7SDag-Erling Smørgrav 		if (rd->_data) {
234*7b5038d7SDag-Erling Smørgrav 			LDNS_FREE(rd->_data);
235*7b5038d7SDag-Erling Smørgrav 		}
236*7b5038d7SDag-Erling Smørgrav 		LDNS_FREE(rd);
237*7b5038d7SDag-Erling Smørgrav 	}
238*7b5038d7SDag-Erling Smørgrav }
239*7b5038d7SDag-Erling Smørgrav 
240*7b5038d7SDag-Erling Smørgrav void
241*7b5038d7SDag-Erling Smørgrav ldns_rdf_free(ldns_rdf *rd)
242*7b5038d7SDag-Erling Smørgrav {
243*7b5038d7SDag-Erling Smørgrav 	if (rd) {
244*7b5038d7SDag-Erling Smørgrav 		LDNS_FREE(rd);
245*7b5038d7SDag-Erling Smørgrav 	}
246*7b5038d7SDag-Erling Smørgrav }
247*7b5038d7SDag-Erling Smørgrav 
248*7b5038d7SDag-Erling Smørgrav ldns_rdf *
249*7b5038d7SDag-Erling Smørgrav ldns_rdf_new_frm_str(ldns_rdf_type type, const char *str)
250*7b5038d7SDag-Erling Smørgrav {
251*7b5038d7SDag-Erling Smørgrav 	ldns_rdf *rdf = NULL;
252*7b5038d7SDag-Erling Smørgrav 	ldns_status status;
253*7b5038d7SDag-Erling Smørgrav 
254*7b5038d7SDag-Erling Smørgrav 	switch (type) {
255*7b5038d7SDag-Erling Smørgrav 	case LDNS_RDF_TYPE_DNAME:
256*7b5038d7SDag-Erling Smørgrav 		status = ldns_str2rdf_dname(&rdf, str);
257*7b5038d7SDag-Erling Smørgrav 		break;
258*7b5038d7SDag-Erling Smørgrav 	case LDNS_RDF_TYPE_INT8:
259*7b5038d7SDag-Erling Smørgrav 		status = ldns_str2rdf_int8(&rdf, str);
260*7b5038d7SDag-Erling Smørgrav 		break;
261*7b5038d7SDag-Erling Smørgrav 	case LDNS_RDF_TYPE_INT16:
262*7b5038d7SDag-Erling Smørgrav 		status = ldns_str2rdf_int16(&rdf, str);
263*7b5038d7SDag-Erling Smørgrav 		break;
264*7b5038d7SDag-Erling Smørgrav 	case LDNS_RDF_TYPE_INT32:
265*7b5038d7SDag-Erling Smørgrav 		status = ldns_str2rdf_int32(&rdf, str);
266*7b5038d7SDag-Erling Smørgrav 		break;
267*7b5038d7SDag-Erling Smørgrav 	case LDNS_RDF_TYPE_A:
268*7b5038d7SDag-Erling Smørgrav 		status = ldns_str2rdf_a(&rdf, str);
269*7b5038d7SDag-Erling Smørgrav 		break;
270*7b5038d7SDag-Erling Smørgrav 	case LDNS_RDF_TYPE_AAAA:
271*7b5038d7SDag-Erling Smørgrav 		status = ldns_str2rdf_aaaa(&rdf, str);
272*7b5038d7SDag-Erling Smørgrav 		break;
273*7b5038d7SDag-Erling Smørgrav 	case LDNS_RDF_TYPE_STR:
274*7b5038d7SDag-Erling Smørgrav 		status = ldns_str2rdf_str(&rdf, str);
275*7b5038d7SDag-Erling Smørgrav 		break;
276*7b5038d7SDag-Erling Smørgrav 	case LDNS_RDF_TYPE_APL:
277*7b5038d7SDag-Erling Smørgrav 		status = ldns_str2rdf_apl(&rdf, str);
278*7b5038d7SDag-Erling Smørgrav 		break;
279*7b5038d7SDag-Erling Smørgrav 	case LDNS_RDF_TYPE_B64:
280*7b5038d7SDag-Erling Smørgrav 		status = ldns_str2rdf_b64(&rdf, str);
281*7b5038d7SDag-Erling Smørgrav 		break;
282*7b5038d7SDag-Erling Smørgrav 	case LDNS_RDF_TYPE_B32_EXT:
283*7b5038d7SDag-Erling Smørgrav 		status = ldns_str2rdf_b32_ext(&rdf, str);
284*7b5038d7SDag-Erling Smørgrav 		break;
285*7b5038d7SDag-Erling Smørgrav 	case LDNS_RDF_TYPE_HEX:
286*7b5038d7SDag-Erling Smørgrav 		status = ldns_str2rdf_hex(&rdf, str);
287*7b5038d7SDag-Erling Smørgrav 		break;
288*7b5038d7SDag-Erling Smørgrav 	case LDNS_RDF_TYPE_NSEC:
289*7b5038d7SDag-Erling Smørgrav 		status = ldns_str2rdf_nsec(&rdf, str);
290*7b5038d7SDag-Erling Smørgrav 		break;
291*7b5038d7SDag-Erling Smørgrav 	case LDNS_RDF_TYPE_TYPE:
292*7b5038d7SDag-Erling Smørgrav 		status = ldns_str2rdf_type(&rdf, str);
293*7b5038d7SDag-Erling Smørgrav 		break;
294*7b5038d7SDag-Erling Smørgrav 	case LDNS_RDF_TYPE_CLASS:
295*7b5038d7SDag-Erling Smørgrav 		status = ldns_str2rdf_class(&rdf, str);
296*7b5038d7SDag-Erling Smørgrav 		break;
297*7b5038d7SDag-Erling Smørgrav 	case LDNS_RDF_TYPE_CERT_ALG:
298*7b5038d7SDag-Erling Smørgrav 		status = ldns_str2rdf_cert_alg(&rdf, str);
299*7b5038d7SDag-Erling Smørgrav 		break;
300*7b5038d7SDag-Erling Smørgrav 	case LDNS_RDF_TYPE_ALG:
301*7b5038d7SDag-Erling Smørgrav 		status = ldns_str2rdf_alg(&rdf, str);
302*7b5038d7SDag-Erling Smørgrav 		break;
303*7b5038d7SDag-Erling Smørgrav 	case LDNS_RDF_TYPE_UNKNOWN:
304*7b5038d7SDag-Erling Smørgrav 		status = ldns_str2rdf_unknown(&rdf, str);
305*7b5038d7SDag-Erling Smørgrav 		break;
306*7b5038d7SDag-Erling Smørgrav 	case LDNS_RDF_TYPE_TIME:
307*7b5038d7SDag-Erling Smørgrav 		status = ldns_str2rdf_time(&rdf, str);
308*7b5038d7SDag-Erling Smørgrav 		break;
309*7b5038d7SDag-Erling Smørgrav 	case LDNS_RDF_TYPE_PERIOD:
310*7b5038d7SDag-Erling Smørgrav 		status = ldns_str2rdf_period(&rdf, str);
311*7b5038d7SDag-Erling Smørgrav 		break;
312*7b5038d7SDag-Erling Smørgrav 	case LDNS_RDF_TYPE_TSIG:
313*7b5038d7SDag-Erling Smørgrav 		status = ldns_str2rdf_tsig(&rdf, str);
314*7b5038d7SDag-Erling Smørgrav 		break;
315*7b5038d7SDag-Erling Smørgrav 	case LDNS_RDF_TYPE_SERVICE:
316*7b5038d7SDag-Erling Smørgrav 		status = ldns_str2rdf_service(&rdf, str);
317*7b5038d7SDag-Erling Smørgrav 		break;
318*7b5038d7SDag-Erling Smørgrav 	case LDNS_RDF_TYPE_LOC:
319*7b5038d7SDag-Erling Smørgrav 		status = ldns_str2rdf_loc(&rdf, str);
320*7b5038d7SDag-Erling Smørgrav 		break;
321*7b5038d7SDag-Erling Smørgrav 	case LDNS_RDF_TYPE_WKS:
322*7b5038d7SDag-Erling Smørgrav 		status = ldns_str2rdf_wks(&rdf, str);
323*7b5038d7SDag-Erling Smørgrav 		break;
324*7b5038d7SDag-Erling Smørgrav 	case LDNS_RDF_TYPE_NSAP:
325*7b5038d7SDag-Erling Smørgrav 		status = ldns_str2rdf_nsap(&rdf, str);
326*7b5038d7SDag-Erling Smørgrav 		break;
327*7b5038d7SDag-Erling Smørgrav 	case LDNS_RDF_TYPE_ATMA:
328*7b5038d7SDag-Erling Smørgrav 		status = ldns_str2rdf_atma(&rdf, str);
329*7b5038d7SDag-Erling Smørgrav 		break;
330*7b5038d7SDag-Erling Smørgrav 	case LDNS_RDF_TYPE_IPSECKEY:
331*7b5038d7SDag-Erling Smørgrav 		status = ldns_str2rdf_ipseckey(&rdf, str);
332*7b5038d7SDag-Erling Smørgrav 		break;
333*7b5038d7SDag-Erling Smørgrav 	case LDNS_RDF_TYPE_NSEC3_SALT:
334*7b5038d7SDag-Erling Smørgrav 		status = ldns_str2rdf_nsec3_salt(&rdf, str);
335*7b5038d7SDag-Erling Smørgrav 		break;
336*7b5038d7SDag-Erling Smørgrav 	case LDNS_RDF_TYPE_NSEC3_NEXT_OWNER:
337*7b5038d7SDag-Erling Smørgrav 		status = ldns_str2rdf_b32_ext(&rdf, str);
338*7b5038d7SDag-Erling Smørgrav 		break;
339*7b5038d7SDag-Erling Smørgrav 	case LDNS_RDF_TYPE_NONE:
340*7b5038d7SDag-Erling Smørgrav 	default:
341*7b5038d7SDag-Erling Smørgrav 		/* default default ??? */
342*7b5038d7SDag-Erling Smørgrav 		status = LDNS_STATUS_ERR;
343*7b5038d7SDag-Erling Smørgrav 		break;
344*7b5038d7SDag-Erling Smørgrav 	}
345*7b5038d7SDag-Erling Smørgrav 	if (LDNS_STATUS_OK == status) {
346*7b5038d7SDag-Erling Smørgrav 		ldns_rdf_set_type(rdf, type);
347*7b5038d7SDag-Erling Smørgrav 		return rdf;
348*7b5038d7SDag-Erling Smørgrav 	}
349*7b5038d7SDag-Erling Smørgrav 	if (rdf) {
350*7b5038d7SDag-Erling Smørgrav 		LDNS_FREE(rdf);
351*7b5038d7SDag-Erling Smørgrav 	}
352*7b5038d7SDag-Erling Smørgrav 	return NULL;
353*7b5038d7SDag-Erling Smørgrav }
354*7b5038d7SDag-Erling Smørgrav 
355*7b5038d7SDag-Erling Smørgrav ldns_status
356*7b5038d7SDag-Erling Smørgrav ldns_rdf_new_frm_fp(ldns_rdf **rdf, ldns_rdf_type type, FILE *fp)
357*7b5038d7SDag-Erling Smørgrav {
358*7b5038d7SDag-Erling Smørgrav 	return ldns_rdf_new_frm_fp_l(rdf, type, fp, NULL);
359*7b5038d7SDag-Erling Smørgrav }
360*7b5038d7SDag-Erling Smørgrav 
361*7b5038d7SDag-Erling Smørgrav ldns_status
362*7b5038d7SDag-Erling Smørgrav ldns_rdf_new_frm_fp_l(ldns_rdf **rdf, ldns_rdf_type type, FILE *fp, int *line_nr)
363*7b5038d7SDag-Erling Smørgrav {
364*7b5038d7SDag-Erling Smørgrav 	char *line;
365*7b5038d7SDag-Erling Smørgrav 	ldns_rdf *r;
366*7b5038d7SDag-Erling Smørgrav 	ssize_t t;
367*7b5038d7SDag-Erling Smørgrav 
368*7b5038d7SDag-Erling Smørgrav 	line = LDNS_XMALLOC(char, LDNS_MAX_LINELEN + 1);
369*7b5038d7SDag-Erling Smørgrav 	if (!line) {
370*7b5038d7SDag-Erling Smørgrav 		return LDNS_STATUS_MEM_ERR;
371*7b5038d7SDag-Erling Smørgrav 	}
372*7b5038d7SDag-Erling Smørgrav 
373*7b5038d7SDag-Erling Smørgrav 	/* read an entire line in from the file */
374*7b5038d7SDag-Erling Smørgrav 	if ((t = ldns_fget_token_l(fp, line, LDNS_PARSE_SKIP_SPACE, 0, line_nr)) == -1 || t == 0) {
375*7b5038d7SDag-Erling Smørgrav 		LDNS_FREE(line);
376*7b5038d7SDag-Erling Smørgrav 		return LDNS_STATUS_SYNTAX_RDATA_ERR;
377*7b5038d7SDag-Erling Smørgrav 	}
378*7b5038d7SDag-Erling Smørgrav 	r =  ldns_rdf_new_frm_str(type, (const char*) line);
379*7b5038d7SDag-Erling Smørgrav 	LDNS_FREE(line);
380*7b5038d7SDag-Erling Smørgrav 	if (rdf) {
381*7b5038d7SDag-Erling Smørgrav 		*rdf = r;
382*7b5038d7SDag-Erling Smørgrav 		return LDNS_STATUS_OK;
383*7b5038d7SDag-Erling Smørgrav 	} else {
384*7b5038d7SDag-Erling Smørgrav 		return LDNS_STATUS_NULL;
385*7b5038d7SDag-Erling Smørgrav 	}
386*7b5038d7SDag-Erling Smørgrav }
387*7b5038d7SDag-Erling Smørgrav 
388*7b5038d7SDag-Erling Smørgrav ldns_rdf *
389*7b5038d7SDag-Erling Smørgrav ldns_rdf_address_reverse(ldns_rdf *rd)
390*7b5038d7SDag-Erling Smørgrav {
391*7b5038d7SDag-Erling Smørgrav 	uint8_t buf_4[LDNS_IP4ADDRLEN];
392*7b5038d7SDag-Erling Smørgrav 	uint8_t buf_6[LDNS_IP6ADDRLEN * 2];
393*7b5038d7SDag-Erling Smørgrav 	ldns_rdf *rev;
394*7b5038d7SDag-Erling Smørgrav 	ldns_rdf *in_addr;
395*7b5038d7SDag-Erling Smørgrav 	ldns_rdf *ret_dname;
396*7b5038d7SDag-Erling Smørgrav 	uint8_t octet;
397*7b5038d7SDag-Erling Smørgrav 	uint8_t nnibble;
398*7b5038d7SDag-Erling Smørgrav 	uint8_t nibble;
399*7b5038d7SDag-Erling Smørgrav 	uint8_t i, j;
400*7b5038d7SDag-Erling Smørgrav 
401*7b5038d7SDag-Erling Smørgrav 	char *char_dname;
402*7b5038d7SDag-Erling Smørgrav 	int nbit;
403*7b5038d7SDag-Erling Smørgrav 
404*7b5038d7SDag-Erling Smørgrav 	if (ldns_rdf_get_type(rd) != LDNS_RDF_TYPE_A &&
405*7b5038d7SDag-Erling Smørgrav 			ldns_rdf_get_type(rd) != LDNS_RDF_TYPE_AAAA) {
406*7b5038d7SDag-Erling Smørgrav 		return NULL;
407*7b5038d7SDag-Erling Smørgrav 	}
408*7b5038d7SDag-Erling Smørgrav 
409*7b5038d7SDag-Erling Smørgrav 	in_addr = NULL;
410*7b5038d7SDag-Erling Smørgrav 	ret_dname = NULL;
411*7b5038d7SDag-Erling Smørgrav 
412*7b5038d7SDag-Erling Smørgrav 	switch(ldns_rdf_get_type(rd)) {
413*7b5038d7SDag-Erling Smørgrav 		case LDNS_RDF_TYPE_A:
414*7b5038d7SDag-Erling Smørgrav 			/* the length of the buffer is 4 */
415*7b5038d7SDag-Erling Smørgrav 			buf_4[3] = ldns_rdf_data(rd)[0];
416*7b5038d7SDag-Erling Smørgrav 			buf_4[2] = ldns_rdf_data(rd)[1];
417*7b5038d7SDag-Erling Smørgrav 			buf_4[1] = ldns_rdf_data(rd)[2];
418*7b5038d7SDag-Erling Smørgrav 			buf_4[0] = ldns_rdf_data(rd)[3];
419*7b5038d7SDag-Erling Smørgrav 			in_addr = ldns_dname_new_frm_str("in-addr.arpa.");
420*7b5038d7SDag-Erling Smørgrav 			if (!in_addr) {
421*7b5038d7SDag-Erling Smørgrav 				return NULL;
422*7b5038d7SDag-Erling Smørgrav 			}
423*7b5038d7SDag-Erling Smørgrav 			/* make a new rdf and convert that back  */
424*7b5038d7SDag-Erling Smørgrav 			rev = ldns_rdf_new_frm_data( LDNS_RDF_TYPE_A,
425*7b5038d7SDag-Erling Smørgrav 				LDNS_IP4ADDRLEN, (void*)&buf_4);
426*7b5038d7SDag-Erling Smørgrav 			if (!rev) {
427*7b5038d7SDag-Erling Smørgrav 				LDNS_FREE(in_addr);
428*7b5038d7SDag-Erling Smørgrav 				return NULL;
429*7b5038d7SDag-Erling Smørgrav 			}
430*7b5038d7SDag-Erling Smørgrav 
431*7b5038d7SDag-Erling Smørgrav 			/* convert rev to a string */
432*7b5038d7SDag-Erling Smørgrav 			char_dname = ldns_rdf2str(rev);
433*7b5038d7SDag-Erling Smørgrav 			if (!char_dname) {
434*7b5038d7SDag-Erling Smørgrav 				LDNS_FREE(in_addr);
435*7b5038d7SDag-Erling Smørgrav 				ldns_rdf_deep_free(rev);
436*7b5038d7SDag-Erling Smørgrav 				return NULL;
437*7b5038d7SDag-Erling Smørgrav 			}
438*7b5038d7SDag-Erling Smørgrav 			/* transform back to rdf with type dname */
439*7b5038d7SDag-Erling Smørgrav 			ret_dname = ldns_dname_new_frm_str(char_dname);
440*7b5038d7SDag-Erling Smørgrav 			if (!ret_dname) {
441*7b5038d7SDag-Erling Smørgrav 				LDNS_FREE(in_addr);
442*7b5038d7SDag-Erling Smørgrav 				ldns_rdf_deep_free(rev);
443*7b5038d7SDag-Erling Smørgrav 				LDNS_FREE(char_dname);
444*7b5038d7SDag-Erling Smørgrav 				return NULL;
445*7b5038d7SDag-Erling Smørgrav 			}
446*7b5038d7SDag-Erling Smørgrav 			/* not needed anymore */
447*7b5038d7SDag-Erling Smørgrav 			ldns_rdf_deep_free(rev);
448*7b5038d7SDag-Erling Smørgrav 			LDNS_FREE(char_dname);
449*7b5038d7SDag-Erling Smørgrav 			break;
450*7b5038d7SDag-Erling Smørgrav 		case LDNS_RDF_TYPE_AAAA:
451*7b5038d7SDag-Erling Smørgrav 			/* some foo magic to reverse the nibbles ... */
452*7b5038d7SDag-Erling Smørgrav 
453*7b5038d7SDag-Erling Smørgrav 			for (nbit = 127; nbit >= 0; nbit = nbit - 4) {
454*7b5038d7SDag-Erling Smørgrav 				/* calculate octett (8 bit) */
455*7b5038d7SDag-Erling Smørgrav 				octet = ( ((unsigned int) nbit) & 0x78) >> 3;
456*7b5038d7SDag-Erling Smørgrav 				/* calculate nibble */
457*7b5038d7SDag-Erling Smørgrav 				nnibble = ( ((unsigned int) nbit) & 0x04) >> 2;
458*7b5038d7SDag-Erling Smørgrav 				/* extract nibble */
459*7b5038d7SDag-Erling Smørgrav 				nibble = (ldns_rdf_data(rd)[octet] & ( 0xf << (4 * (1 -
460*7b5038d7SDag-Erling Smørgrav 						 nnibble)) ) ) >> ( 4 * (1 -
461*7b5038d7SDag-Erling Smørgrav 						nnibble));
462*7b5038d7SDag-Erling Smørgrav 
463*7b5038d7SDag-Erling Smørgrav 				buf_6[(LDNS_IP6ADDRLEN * 2 - 1) -
464*7b5038d7SDag-Erling Smørgrav 					(octet * 2 + nnibble)] =
465*7b5038d7SDag-Erling Smørgrav 						(uint8_t)ldns_int_to_hexdigit((int)nibble);
466*7b5038d7SDag-Erling Smørgrav 			}
467*7b5038d7SDag-Erling Smørgrav 
468*7b5038d7SDag-Erling Smørgrav 			char_dname = LDNS_XMALLOC(char, (LDNS_IP6ADDRLEN * 4));
469*7b5038d7SDag-Erling Smørgrav 			if (!char_dname) {
470*7b5038d7SDag-Erling Smørgrav 				return NULL;
471*7b5038d7SDag-Erling Smørgrav 			}
472*7b5038d7SDag-Erling Smørgrav 			char_dname[LDNS_IP6ADDRLEN * 4 - 1] = '\0'; /* closure */
473*7b5038d7SDag-Erling Smørgrav 
474*7b5038d7SDag-Erling Smørgrav 			/* walk the string and add . 's */
475*7b5038d7SDag-Erling Smørgrav 			for (i = 0, j = 0; i < LDNS_IP6ADDRLEN * 2; i++, j = j + 2) {
476*7b5038d7SDag-Erling Smørgrav 				char_dname[j] = (char)buf_6[i];
477*7b5038d7SDag-Erling Smørgrav 				if (i != LDNS_IP6ADDRLEN * 2 - 1) {
478*7b5038d7SDag-Erling Smørgrav 					char_dname[j + 1] = '.';
479*7b5038d7SDag-Erling Smørgrav 				}
480*7b5038d7SDag-Erling Smørgrav 			}
481*7b5038d7SDag-Erling Smørgrav 			in_addr = ldns_dname_new_frm_str("ip6.arpa.");
482*7b5038d7SDag-Erling Smørgrav 			if (!in_addr) {
483*7b5038d7SDag-Erling Smørgrav 				LDNS_FREE(char_dname);
484*7b5038d7SDag-Erling Smørgrav 				return NULL;
485*7b5038d7SDag-Erling Smørgrav 			}
486*7b5038d7SDag-Erling Smørgrav 
487*7b5038d7SDag-Erling Smørgrav 			/* convert rev to a string */
488*7b5038d7SDag-Erling Smørgrav 			ret_dname = ldns_dname_new_frm_str(char_dname);
489*7b5038d7SDag-Erling Smørgrav 			LDNS_FREE(char_dname);
490*7b5038d7SDag-Erling Smørgrav 			if (!ret_dname) {
491*7b5038d7SDag-Erling Smørgrav 				ldns_rdf_deep_free(in_addr);
492*7b5038d7SDag-Erling Smørgrav 				return NULL;
493*7b5038d7SDag-Erling Smørgrav 			}
494*7b5038d7SDag-Erling Smørgrav 			break;
495*7b5038d7SDag-Erling Smørgrav 		default:
496*7b5038d7SDag-Erling Smørgrav 			break;
497*7b5038d7SDag-Erling Smørgrav 	}
498*7b5038d7SDag-Erling Smørgrav 	/* add the suffix */
499*7b5038d7SDag-Erling Smørgrav 	rev = ldns_dname_cat_clone(ret_dname, in_addr);
500*7b5038d7SDag-Erling Smørgrav 
501*7b5038d7SDag-Erling Smørgrav 	ldns_rdf_deep_free(ret_dname);
502*7b5038d7SDag-Erling Smørgrav 	ldns_rdf_deep_free(in_addr);
503*7b5038d7SDag-Erling Smørgrav 	return rev;
504*7b5038d7SDag-Erling Smørgrav }
505*7b5038d7SDag-Erling Smørgrav 
506*7b5038d7SDag-Erling Smørgrav ldns_status
507*7b5038d7SDag-Erling Smørgrav ldns_octet(char *word, size_t *length)
508*7b5038d7SDag-Erling Smørgrav {
509*7b5038d7SDag-Erling Smørgrav     char *s;
510*7b5038d7SDag-Erling Smørgrav     char *p;
511*7b5038d7SDag-Erling Smørgrav     *length = 0;
512*7b5038d7SDag-Erling Smørgrav 
513*7b5038d7SDag-Erling Smørgrav     for (s = p = word; *s != '\0'; s++,p++) {
514*7b5038d7SDag-Erling Smørgrav         switch (*s) {
515*7b5038d7SDag-Erling Smørgrav             case '.':
516*7b5038d7SDag-Erling Smørgrav                 if (s[1] == '.') {
517*7b5038d7SDag-Erling Smørgrav 		    return LDNS_STATUS_EMPTY_LABEL;
518*7b5038d7SDag-Erling Smørgrav                 }
519*7b5038d7SDag-Erling Smørgrav                 *p = *s;
520*7b5038d7SDag-Erling Smørgrav                 (*length)++;
521*7b5038d7SDag-Erling Smørgrav                 break;
522*7b5038d7SDag-Erling Smørgrav             case '\\':
523*7b5038d7SDag-Erling Smørgrav                 if ('0' <= s[1] && s[1] <= '9' &&
524*7b5038d7SDag-Erling Smørgrav                     '0' <= s[2] && s[2] <= '9' &&
525*7b5038d7SDag-Erling Smørgrav                     '0' <= s[3] && s[3] <= '9') {
526*7b5038d7SDag-Erling Smørgrav                     /* \DDD seen */
527*7b5038d7SDag-Erling Smørgrav                     int val = ((s[1] - '0') * 100 +
528*7b5038d7SDag-Erling Smørgrav                            (s[2] - '0') * 10 + (s[3] - '0'));
529*7b5038d7SDag-Erling Smørgrav 
530*7b5038d7SDag-Erling Smørgrav                     if (0 <= val && val <= 255) {
531*7b5038d7SDag-Erling Smørgrav                         /* this also handles \0 */
532*7b5038d7SDag-Erling Smørgrav                         s += 3;
533*7b5038d7SDag-Erling Smørgrav                         *p = val;
534*7b5038d7SDag-Erling Smørgrav                         (*length)++;
535*7b5038d7SDag-Erling Smørgrav                     } else {
536*7b5038d7SDag-Erling Smørgrav                         return LDNS_STATUS_DDD_OVERFLOW;
537*7b5038d7SDag-Erling Smørgrav                     }
538*7b5038d7SDag-Erling Smørgrav                 } else {
539*7b5038d7SDag-Erling Smørgrav                     /* an espaced character, like \<space> ?
540*7b5038d7SDag-Erling Smørgrav                     * remove the '\' keep the rest */
541*7b5038d7SDag-Erling Smørgrav                     *p = *++s;
542*7b5038d7SDag-Erling Smørgrav                     (*length)++;
543*7b5038d7SDag-Erling Smørgrav                 }
544*7b5038d7SDag-Erling Smørgrav                 break;
545*7b5038d7SDag-Erling Smørgrav             case '\"':
546*7b5038d7SDag-Erling Smørgrav                 /* non quoted " Is either first or the last character in
547*7b5038d7SDag-Erling Smørgrav                  * the string */
548*7b5038d7SDag-Erling Smørgrav 
549*7b5038d7SDag-Erling Smørgrav                 *p = *++s; /* skip it */
550*7b5038d7SDag-Erling Smørgrav                 (*length)++;
551*7b5038d7SDag-Erling Smørgrav 		/* I'm not sure if this is needed in libdns... MG */
552*7b5038d7SDag-Erling Smørgrav                 if ( *s == '\0' ) {
553*7b5038d7SDag-Erling Smørgrav                     /* ok, it was the last one */
554*7b5038d7SDag-Erling Smørgrav                     *p  = '\0';
555*7b5038d7SDag-Erling Smørgrav 		    return LDNS_STATUS_OK;
556*7b5038d7SDag-Erling Smørgrav                 }
557*7b5038d7SDag-Erling Smørgrav                 break;
558*7b5038d7SDag-Erling Smørgrav             default:
559*7b5038d7SDag-Erling Smørgrav                 *p = *s;
560*7b5038d7SDag-Erling Smørgrav                 (*length)++;
561*7b5038d7SDag-Erling Smørgrav                 break;
562*7b5038d7SDag-Erling Smørgrav         }
563*7b5038d7SDag-Erling Smørgrav     }
564*7b5038d7SDag-Erling Smørgrav     *p = '\0';
565*7b5038d7SDag-Erling Smørgrav     return LDNS_STATUS_OK;
566*7b5038d7SDag-Erling Smørgrav }
567*7b5038d7SDag-Erling Smørgrav 
568*7b5038d7SDag-Erling Smørgrav int
569*7b5038d7SDag-Erling Smørgrav ldns_rdf_compare(const ldns_rdf *rd1, const ldns_rdf *rd2)
570*7b5038d7SDag-Erling Smørgrav {
571*7b5038d7SDag-Erling Smørgrav 	uint16_t i1, i2, i;
572*7b5038d7SDag-Erling Smørgrav 	uint8_t *d1, *d2;
573*7b5038d7SDag-Erling Smørgrav 
574*7b5038d7SDag-Erling Smørgrav 	/* only when both are not NULL we can say anything about them */
575*7b5038d7SDag-Erling Smørgrav 	if (!rd1 && !rd2) {
576*7b5038d7SDag-Erling Smørgrav 		return 0;
577*7b5038d7SDag-Erling Smørgrav 	}
578*7b5038d7SDag-Erling Smørgrav 	if (!rd1 || !rd2) {
579*7b5038d7SDag-Erling Smørgrav 		return -1;
580*7b5038d7SDag-Erling Smørgrav 	}
581*7b5038d7SDag-Erling Smørgrav 	i1 = ldns_rdf_size(rd1);
582*7b5038d7SDag-Erling Smørgrav 	i2 = ldns_rdf_size(rd2);
583*7b5038d7SDag-Erling Smørgrav 
584*7b5038d7SDag-Erling Smørgrav 	if (i1 < i2) {
585*7b5038d7SDag-Erling Smørgrav 		return -1;
586*7b5038d7SDag-Erling Smørgrav 	} else if (i1 > i2) {
587*7b5038d7SDag-Erling Smørgrav 		return +1;
588*7b5038d7SDag-Erling Smørgrav 	} else {
589*7b5038d7SDag-Erling Smørgrav 		d1 = (uint8_t*)ldns_rdf_data(rd1);
590*7b5038d7SDag-Erling Smørgrav 		d2 = (uint8_t*)ldns_rdf_data(rd2);
591*7b5038d7SDag-Erling Smørgrav 		for(i = 0; i < i1; i++) {
592*7b5038d7SDag-Erling Smørgrav 			if (d1[i] < d2[i]) {
593*7b5038d7SDag-Erling Smørgrav 				return -1;
594*7b5038d7SDag-Erling Smørgrav 			} else if (d1[i] > d2[i]) {
595*7b5038d7SDag-Erling Smørgrav 				return +1;
596*7b5038d7SDag-Erling Smørgrav 			}
597*7b5038d7SDag-Erling Smørgrav 		}
598*7b5038d7SDag-Erling Smørgrav 	}
599*7b5038d7SDag-Erling Smørgrav 	return 0;
600*7b5038d7SDag-Erling Smørgrav }
601*7b5038d7SDag-Erling Smørgrav 
602*7b5038d7SDag-Erling Smørgrav uint32_t
603*7b5038d7SDag-Erling Smørgrav ldns_str2period(const char *nptr, const char **endptr)
604*7b5038d7SDag-Erling Smørgrav {
605*7b5038d7SDag-Erling Smørgrav 	int sign = 0;
606*7b5038d7SDag-Erling Smørgrav 	uint32_t i = 0;
607*7b5038d7SDag-Erling Smørgrav 	uint32_t seconds = 0;
608*7b5038d7SDag-Erling Smørgrav 
609*7b5038d7SDag-Erling Smørgrav 	for(*endptr = nptr; **endptr; (*endptr)++) {
610*7b5038d7SDag-Erling Smørgrav 		switch (**endptr) {
611*7b5038d7SDag-Erling Smørgrav 			case ' ':
612*7b5038d7SDag-Erling Smørgrav 			case '\t':
613*7b5038d7SDag-Erling Smørgrav 				break;
614*7b5038d7SDag-Erling Smørgrav 			case '-':
615*7b5038d7SDag-Erling Smørgrav 				if(sign == 0) {
616*7b5038d7SDag-Erling Smørgrav 					sign = -1;
617*7b5038d7SDag-Erling Smørgrav 				} else {
618*7b5038d7SDag-Erling Smørgrav 					return seconds;
619*7b5038d7SDag-Erling Smørgrav 				}
620*7b5038d7SDag-Erling Smørgrav 				break;
621*7b5038d7SDag-Erling Smørgrav 			case '+':
622*7b5038d7SDag-Erling Smørgrav 				if(sign == 0) {
623*7b5038d7SDag-Erling Smørgrav 					sign = 1;
624*7b5038d7SDag-Erling Smørgrav 				} else {
625*7b5038d7SDag-Erling Smørgrav 					return seconds;
626*7b5038d7SDag-Erling Smørgrav 				}
627*7b5038d7SDag-Erling Smørgrav 				break;
628*7b5038d7SDag-Erling Smørgrav 			case 's':
629*7b5038d7SDag-Erling Smørgrav 			case 'S':
630*7b5038d7SDag-Erling Smørgrav 				seconds += i;
631*7b5038d7SDag-Erling Smørgrav 				i = 0;
632*7b5038d7SDag-Erling Smørgrav 				break;
633*7b5038d7SDag-Erling Smørgrav 			case 'm':
634*7b5038d7SDag-Erling Smørgrav 			case 'M':
635*7b5038d7SDag-Erling Smørgrav 				seconds += i * 60;
636*7b5038d7SDag-Erling Smørgrav 				i = 0;
637*7b5038d7SDag-Erling Smørgrav 				break;
638*7b5038d7SDag-Erling Smørgrav 			case 'h':
639*7b5038d7SDag-Erling Smørgrav 			case 'H':
640*7b5038d7SDag-Erling Smørgrav 				seconds += i * 60 * 60;
641*7b5038d7SDag-Erling Smørgrav 				i = 0;
642*7b5038d7SDag-Erling Smørgrav 				break;
643*7b5038d7SDag-Erling Smørgrav 			case 'd':
644*7b5038d7SDag-Erling Smørgrav 			case 'D':
645*7b5038d7SDag-Erling Smørgrav 				seconds += i * 60 * 60 * 24;
646*7b5038d7SDag-Erling Smørgrav 				i = 0;
647*7b5038d7SDag-Erling Smørgrav 				break;
648*7b5038d7SDag-Erling Smørgrav 			case 'w':
649*7b5038d7SDag-Erling Smørgrav 			case 'W':
650*7b5038d7SDag-Erling Smørgrav 				seconds += i * 60 * 60 * 24 * 7;
651*7b5038d7SDag-Erling Smørgrav 				i = 0;
652*7b5038d7SDag-Erling Smørgrav 				break;
653*7b5038d7SDag-Erling Smørgrav 			case '0':
654*7b5038d7SDag-Erling Smørgrav 			case '1':
655*7b5038d7SDag-Erling Smørgrav 			case '2':
656*7b5038d7SDag-Erling Smørgrav 			case '3':
657*7b5038d7SDag-Erling Smørgrav 			case '4':
658*7b5038d7SDag-Erling Smørgrav 			case '5':
659*7b5038d7SDag-Erling Smørgrav 			case '6':
660*7b5038d7SDag-Erling Smørgrav 			case '7':
661*7b5038d7SDag-Erling Smørgrav 			case '8':
662*7b5038d7SDag-Erling Smørgrav 			case '9':
663*7b5038d7SDag-Erling Smørgrav 				i *= 10;
664*7b5038d7SDag-Erling Smørgrav 				i += (**endptr - '0');
665*7b5038d7SDag-Erling Smørgrav 				break;
666*7b5038d7SDag-Erling Smørgrav 			default:
667*7b5038d7SDag-Erling Smørgrav 				seconds += i;
668*7b5038d7SDag-Erling Smørgrav 				/* disregard signedness */
669*7b5038d7SDag-Erling Smørgrav 				return seconds;
670*7b5038d7SDag-Erling Smørgrav 		}
671*7b5038d7SDag-Erling Smørgrav 	}
672*7b5038d7SDag-Erling Smørgrav 	seconds += i;
673*7b5038d7SDag-Erling Smørgrav 	/* disregard signedness */
674*7b5038d7SDag-Erling Smørgrav 	return seconds;
675*7b5038d7SDag-Erling Smørgrav }
676