1825eb42bSJan Lentfer /*
2825eb42bSJan Lentfer * rdata.c
3825eb42bSJan Lentfer *
4825eb42bSJan Lentfer * rdata implementation
5825eb42bSJan Lentfer *
6825eb42bSJan Lentfer * a Net::DNS like library for C
7825eb42bSJan Lentfer *
8825eb42bSJan Lentfer * (c) NLnet Labs, 2004-2006
9825eb42bSJan Lentfer *
10825eb42bSJan Lentfer * See the file LICENSE for the license
11825eb42bSJan Lentfer */
12825eb42bSJan Lentfer
13825eb42bSJan Lentfer #include <ldns/config.h>
14825eb42bSJan Lentfer
15825eb42bSJan Lentfer #include <ldns/ldns.h>
16825eb42bSJan Lentfer
17825eb42bSJan Lentfer /*
18825eb42bSJan Lentfer * Access functions
19825eb42bSJan Lentfer * do this as functions to get type checking
20825eb42bSJan Lentfer */
21825eb42bSJan Lentfer
22825eb42bSJan Lentfer /* read */
23825eb42bSJan Lentfer size_t
ldns_rdf_size(const ldns_rdf * rd)24825eb42bSJan Lentfer ldns_rdf_size(const ldns_rdf *rd)
25825eb42bSJan Lentfer {
26825eb42bSJan Lentfer assert(rd != NULL);
27825eb42bSJan Lentfer return rd->_size;
28825eb42bSJan Lentfer }
29825eb42bSJan Lentfer
30825eb42bSJan Lentfer ldns_rdf_type
ldns_rdf_get_type(const ldns_rdf * rd)31825eb42bSJan Lentfer ldns_rdf_get_type(const ldns_rdf *rd)
32825eb42bSJan Lentfer {
33825eb42bSJan Lentfer assert(rd != NULL);
34825eb42bSJan Lentfer return rd->_type;
35825eb42bSJan Lentfer }
36825eb42bSJan Lentfer
37825eb42bSJan Lentfer uint8_t *
ldns_rdf_data(const ldns_rdf * rd)38825eb42bSJan Lentfer ldns_rdf_data(const ldns_rdf *rd)
39825eb42bSJan Lentfer {
40825eb42bSJan Lentfer assert(rd != NULL);
41825eb42bSJan Lentfer return rd->_data;
42825eb42bSJan Lentfer }
43825eb42bSJan Lentfer
44825eb42bSJan Lentfer /* write */
45825eb42bSJan Lentfer void
ldns_rdf_set_size(ldns_rdf * rd,size_t size)46825eb42bSJan Lentfer ldns_rdf_set_size(ldns_rdf *rd, size_t size)
47825eb42bSJan Lentfer {
48825eb42bSJan Lentfer assert(rd != NULL);
49825eb42bSJan Lentfer rd->_size = size;
50825eb42bSJan Lentfer }
51825eb42bSJan Lentfer
52825eb42bSJan Lentfer void
ldns_rdf_set_type(ldns_rdf * rd,ldns_rdf_type type)53825eb42bSJan Lentfer ldns_rdf_set_type(ldns_rdf *rd, ldns_rdf_type type)
54825eb42bSJan Lentfer {
55825eb42bSJan Lentfer assert(rd != NULL);
56825eb42bSJan Lentfer rd->_type = type;
57825eb42bSJan Lentfer }
58825eb42bSJan Lentfer
59825eb42bSJan Lentfer void
ldns_rdf_set_data(ldns_rdf * rd,void * data)60825eb42bSJan Lentfer ldns_rdf_set_data(ldns_rdf *rd, void *data)
61825eb42bSJan Lentfer {
62825eb42bSJan Lentfer /* only copy the pointer */
63825eb42bSJan Lentfer assert(rd != NULL);
64825eb42bSJan Lentfer rd->_data = data;
65825eb42bSJan Lentfer }
66825eb42bSJan Lentfer
67825eb42bSJan Lentfer /* for types that allow it, return
68825eb42bSJan Lentfer * the native/host order type */
69825eb42bSJan Lentfer uint8_t
ldns_rdf2native_int8(const ldns_rdf * rd)70825eb42bSJan Lentfer ldns_rdf2native_int8(const ldns_rdf *rd)
71825eb42bSJan Lentfer {
72825eb42bSJan Lentfer uint8_t data;
73825eb42bSJan Lentfer
74825eb42bSJan Lentfer /* only allow 8 bit rdfs */
75825eb42bSJan Lentfer if (ldns_rdf_size(rd) != LDNS_RDF_SIZE_BYTE) {
76825eb42bSJan Lentfer return 0;
77825eb42bSJan Lentfer }
78825eb42bSJan Lentfer
79825eb42bSJan Lentfer memcpy(&data, ldns_rdf_data(rd), sizeof(data));
80825eb42bSJan Lentfer return data;
81825eb42bSJan Lentfer }
82825eb42bSJan Lentfer
83825eb42bSJan Lentfer uint16_t
ldns_rdf2native_int16(const ldns_rdf * rd)84825eb42bSJan Lentfer ldns_rdf2native_int16(const ldns_rdf *rd)
85825eb42bSJan Lentfer {
86825eb42bSJan Lentfer uint16_t data;
87825eb42bSJan Lentfer
88825eb42bSJan Lentfer /* only allow 16 bit rdfs */
89825eb42bSJan Lentfer if (ldns_rdf_size(rd) != LDNS_RDF_SIZE_WORD) {
90825eb42bSJan Lentfer return 0;
91825eb42bSJan Lentfer }
92825eb42bSJan Lentfer
93825eb42bSJan Lentfer memcpy(&data, ldns_rdf_data(rd), sizeof(data));
94825eb42bSJan Lentfer return ntohs(data);
95825eb42bSJan Lentfer }
96825eb42bSJan Lentfer
97825eb42bSJan Lentfer uint32_t
ldns_rdf2native_int32(const ldns_rdf * rd)98825eb42bSJan Lentfer ldns_rdf2native_int32(const ldns_rdf *rd)
99825eb42bSJan Lentfer {
100825eb42bSJan Lentfer uint32_t data;
101825eb42bSJan Lentfer
102825eb42bSJan Lentfer /* only allow 32 bit rdfs */
103825eb42bSJan Lentfer if (ldns_rdf_size(rd) != LDNS_RDF_SIZE_DOUBLEWORD) {
104825eb42bSJan Lentfer return 0;
105825eb42bSJan Lentfer }
106825eb42bSJan Lentfer
107825eb42bSJan Lentfer memcpy(&data, ldns_rdf_data(rd), sizeof(data));
108825eb42bSJan Lentfer return ntohl(data);
109825eb42bSJan Lentfer }
110825eb42bSJan Lentfer
111825eb42bSJan Lentfer time_t
ldns_rdf2native_time_t(const ldns_rdf * rd)112825eb42bSJan Lentfer ldns_rdf2native_time_t(const ldns_rdf *rd)
113825eb42bSJan Lentfer {
114825eb42bSJan Lentfer uint32_t data;
115825eb42bSJan Lentfer
1165340022aSzrj /* only allow 32 bit rdfs */
1175340022aSzrj if (ldns_rdf_size(rd) != LDNS_RDF_SIZE_DOUBLEWORD ||
1185340022aSzrj ldns_rdf_get_type(rd) != LDNS_RDF_TYPE_TIME) {
119825eb42bSJan Lentfer return 0;
120825eb42bSJan Lentfer }
1215340022aSzrj memcpy(&data, ldns_rdf_data(rd), sizeof(data));
1225340022aSzrj return (time_t)ntohl(data);
123825eb42bSJan Lentfer }
124825eb42bSJan Lentfer
125825eb42bSJan Lentfer ldns_rdf *
ldns_native2rdf_int8(ldns_rdf_type type,uint8_t value)126825eb42bSJan Lentfer ldns_native2rdf_int8(ldns_rdf_type type, uint8_t value)
127825eb42bSJan Lentfer {
128825eb42bSJan Lentfer return ldns_rdf_new_frm_data(type, LDNS_RDF_SIZE_BYTE, &value);
129825eb42bSJan Lentfer }
130825eb42bSJan Lentfer
131825eb42bSJan Lentfer ldns_rdf *
ldns_native2rdf_int16(ldns_rdf_type type,uint16_t value)132825eb42bSJan Lentfer ldns_native2rdf_int16(ldns_rdf_type type, uint16_t value)
133825eb42bSJan Lentfer {
134825eb42bSJan Lentfer uint16_t *rdf_data = LDNS_XMALLOC(uint16_t, 1);
135ac996e71SJan Lentfer ldns_rdf* rdf;
136825eb42bSJan Lentfer if (!rdf_data) {
137825eb42bSJan Lentfer return NULL;
138825eb42bSJan Lentfer }
139825eb42bSJan Lentfer ldns_write_uint16(rdf_data, value);
140ac996e71SJan Lentfer rdf = ldns_rdf_new(type, LDNS_RDF_SIZE_WORD, rdf_data);
141ac996e71SJan Lentfer if(!rdf)
142ac996e71SJan Lentfer LDNS_FREE(rdf_data);
143ac996e71SJan Lentfer return rdf;
144825eb42bSJan Lentfer }
145825eb42bSJan Lentfer
146825eb42bSJan Lentfer ldns_rdf *
ldns_native2rdf_int32(ldns_rdf_type type,uint32_t value)147825eb42bSJan Lentfer ldns_native2rdf_int32(ldns_rdf_type type, uint32_t value)
148825eb42bSJan Lentfer {
149825eb42bSJan Lentfer uint32_t *rdf_data = LDNS_XMALLOC(uint32_t, 1);
150ac996e71SJan Lentfer ldns_rdf* rdf;
151825eb42bSJan Lentfer if (!rdf_data) {
152825eb42bSJan Lentfer return NULL;
153825eb42bSJan Lentfer }
154825eb42bSJan Lentfer ldns_write_uint32(rdf_data, value);
155ac996e71SJan Lentfer rdf = ldns_rdf_new(type, LDNS_RDF_SIZE_DOUBLEWORD, rdf_data);
156ac996e71SJan Lentfer if(!rdf)
157ac996e71SJan Lentfer LDNS_FREE(rdf_data);
158ac996e71SJan Lentfer return rdf;
159825eb42bSJan Lentfer }
160825eb42bSJan Lentfer
161825eb42bSJan Lentfer ldns_rdf *
ldns_native2rdf_int16_data(size_t size,uint8_t * data)162825eb42bSJan Lentfer ldns_native2rdf_int16_data(size_t size, uint8_t *data)
163825eb42bSJan Lentfer {
164825eb42bSJan Lentfer uint8_t *rdf_data = LDNS_XMALLOC(uint8_t, size + 2);
165ac996e71SJan Lentfer ldns_rdf* rdf;
166825eb42bSJan Lentfer if (!rdf_data) {
167825eb42bSJan Lentfer return NULL;
168825eb42bSJan Lentfer }
169825eb42bSJan Lentfer ldns_write_uint16(rdf_data, size);
170825eb42bSJan Lentfer memcpy(rdf_data + 2, data, size);
171ac996e71SJan Lentfer rdf = ldns_rdf_new(LDNS_RDF_TYPE_INT16_DATA, size + 2, rdf_data);
172ac996e71SJan Lentfer if(!rdf)
173ac996e71SJan Lentfer LDNS_FREE(rdf_data);
174ac996e71SJan Lentfer return rdf;
175825eb42bSJan Lentfer }
176825eb42bSJan Lentfer
177825eb42bSJan Lentfer /* note: data must be allocated memory */
178825eb42bSJan Lentfer ldns_rdf *
ldns_rdf_new(ldns_rdf_type type,size_t size,void * data)179825eb42bSJan Lentfer ldns_rdf_new(ldns_rdf_type type, size_t size, void *data)
180825eb42bSJan Lentfer {
181825eb42bSJan Lentfer ldns_rdf *rd;
182825eb42bSJan Lentfer rd = LDNS_MALLOC(ldns_rdf);
183825eb42bSJan Lentfer if (!rd) {
184825eb42bSJan Lentfer return NULL;
185825eb42bSJan Lentfer }
186825eb42bSJan Lentfer ldns_rdf_set_size(rd, size);
187825eb42bSJan Lentfer ldns_rdf_set_type(rd, type);
188825eb42bSJan Lentfer ldns_rdf_set_data(rd, data);
189825eb42bSJan Lentfer return rd;
190825eb42bSJan Lentfer }
191825eb42bSJan Lentfer
192825eb42bSJan Lentfer ldns_rdf *
ldns_rdf_new_frm_data(ldns_rdf_type type,size_t size,const void * data)193825eb42bSJan Lentfer ldns_rdf_new_frm_data(ldns_rdf_type type, size_t size, const void *data)
194825eb42bSJan Lentfer {
195825eb42bSJan Lentfer ldns_rdf *rdf;
196825eb42bSJan Lentfer
197825eb42bSJan Lentfer /* if the size is too big, fail */
198825eb42bSJan Lentfer if (size > LDNS_MAX_RDFLEN) {
199825eb42bSJan Lentfer return NULL;
200825eb42bSJan Lentfer }
201825eb42bSJan Lentfer
202825eb42bSJan Lentfer /* allocate space */
203825eb42bSJan Lentfer rdf = LDNS_MALLOC(ldns_rdf);
204825eb42bSJan Lentfer if (!rdf) {
205825eb42bSJan Lentfer return NULL;
206825eb42bSJan Lentfer }
207825eb42bSJan Lentfer rdf->_data = LDNS_XMALLOC(uint8_t, size);
208825eb42bSJan Lentfer if (!rdf->_data) {
209825eb42bSJan Lentfer LDNS_FREE(rdf);
210825eb42bSJan Lentfer return NULL;
211825eb42bSJan Lentfer }
212825eb42bSJan Lentfer
213825eb42bSJan Lentfer /* set the values */
214825eb42bSJan Lentfer ldns_rdf_set_type(rdf, type);
215825eb42bSJan Lentfer ldns_rdf_set_size(rdf, size);
216825eb42bSJan Lentfer memcpy(rdf->_data, data, size);
217825eb42bSJan Lentfer
218825eb42bSJan Lentfer return rdf;
219825eb42bSJan Lentfer }
220825eb42bSJan Lentfer
221825eb42bSJan Lentfer ldns_rdf *
ldns_rdf_clone(const ldns_rdf * rd)222825eb42bSJan Lentfer ldns_rdf_clone(const ldns_rdf *rd)
223825eb42bSJan Lentfer {
224825eb42bSJan Lentfer assert(rd != NULL);
225825eb42bSJan Lentfer return (ldns_rdf_new_frm_data( ldns_rdf_get_type(rd),
226825eb42bSJan Lentfer ldns_rdf_size(rd), ldns_rdf_data(rd)));
227825eb42bSJan Lentfer }
228825eb42bSJan Lentfer
229825eb42bSJan Lentfer void
ldns_rdf_deep_free(ldns_rdf * rd)230825eb42bSJan Lentfer ldns_rdf_deep_free(ldns_rdf *rd)
231825eb42bSJan Lentfer {
232825eb42bSJan Lentfer if (rd) {
233825eb42bSJan Lentfer if (rd->_data) {
234825eb42bSJan Lentfer LDNS_FREE(rd->_data);
235825eb42bSJan Lentfer }
236825eb42bSJan Lentfer LDNS_FREE(rd);
237825eb42bSJan Lentfer }
238825eb42bSJan Lentfer }
239825eb42bSJan Lentfer
240825eb42bSJan Lentfer void
ldns_rdf_free(ldns_rdf * rd)241825eb42bSJan Lentfer ldns_rdf_free(ldns_rdf *rd)
242825eb42bSJan Lentfer {
243825eb42bSJan Lentfer if (rd) {
244825eb42bSJan Lentfer LDNS_FREE(rd);
245825eb42bSJan Lentfer }
246825eb42bSJan Lentfer }
247825eb42bSJan Lentfer
248825eb42bSJan Lentfer ldns_rdf *
ldns_rdf_new_frm_str(ldns_rdf_type type,const char * str)249825eb42bSJan Lentfer ldns_rdf_new_frm_str(ldns_rdf_type type, const char *str)
250825eb42bSJan Lentfer {
251825eb42bSJan Lentfer ldns_rdf *rdf = NULL;
252825eb42bSJan Lentfer ldns_status status;
253825eb42bSJan Lentfer
254825eb42bSJan Lentfer switch (type) {
255825eb42bSJan Lentfer case LDNS_RDF_TYPE_DNAME:
256825eb42bSJan Lentfer status = ldns_str2rdf_dname(&rdf, str);
257825eb42bSJan Lentfer break;
258825eb42bSJan Lentfer case LDNS_RDF_TYPE_INT8:
259825eb42bSJan Lentfer status = ldns_str2rdf_int8(&rdf, str);
260825eb42bSJan Lentfer break;
261825eb42bSJan Lentfer case LDNS_RDF_TYPE_INT16:
262825eb42bSJan Lentfer status = ldns_str2rdf_int16(&rdf, str);
263825eb42bSJan Lentfer break;
264825eb42bSJan Lentfer case LDNS_RDF_TYPE_INT32:
265825eb42bSJan Lentfer status = ldns_str2rdf_int32(&rdf, str);
266825eb42bSJan Lentfer break;
267825eb42bSJan Lentfer case LDNS_RDF_TYPE_A:
268825eb42bSJan Lentfer status = ldns_str2rdf_a(&rdf, str);
269825eb42bSJan Lentfer break;
270825eb42bSJan Lentfer case LDNS_RDF_TYPE_AAAA:
271825eb42bSJan Lentfer status = ldns_str2rdf_aaaa(&rdf, str);
272825eb42bSJan Lentfer break;
273825eb42bSJan Lentfer case LDNS_RDF_TYPE_STR:
274825eb42bSJan Lentfer status = ldns_str2rdf_str(&rdf, str);
275825eb42bSJan Lentfer break;
276825eb42bSJan Lentfer case LDNS_RDF_TYPE_APL:
277825eb42bSJan Lentfer status = ldns_str2rdf_apl(&rdf, str);
278825eb42bSJan Lentfer break;
279825eb42bSJan Lentfer case LDNS_RDF_TYPE_B64:
280825eb42bSJan Lentfer status = ldns_str2rdf_b64(&rdf, str);
281825eb42bSJan Lentfer break;
282825eb42bSJan Lentfer case LDNS_RDF_TYPE_B32_EXT:
283825eb42bSJan Lentfer status = ldns_str2rdf_b32_ext(&rdf, str);
284825eb42bSJan Lentfer break;
285825eb42bSJan Lentfer case LDNS_RDF_TYPE_HEX:
286825eb42bSJan Lentfer status = ldns_str2rdf_hex(&rdf, str);
287825eb42bSJan Lentfer break;
288825eb42bSJan Lentfer case LDNS_RDF_TYPE_NSEC:
289825eb42bSJan Lentfer status = ldns_str2rdf_nsec(&rdf, str);
290825eb42bSJan Lentfer break;
291825eb42bSJan Lentfer case LDNS_RDF_TYPE_TYPE:
292825eb42bSJan Lentfer status = ldns_str2rdf_type(&rdf, str);
293825eb42bSJan Lentfer break;
294825eb42bSJan Lentfer case LDNS_RDF_TYPE_CLASS:
295825eb42bSJan Lentfer status = ldns_str2rdf_class(&rdf, str);
296825eb42bSJan Lentfer break;
297825eb42bSJan Lentfer case LDNS_RDF_TYPE_CERT_ALG:
298825eb42bSJan Lentfer status = ldns_str2rdf_cert_alg(&rdf, str);
299825eb42bSJan Lentfer break;
300825eb42bSJan Lentfer case LDNS_RDF_TYPE_ALG:
301825eb42bSJan Lentfer status = ldns_str2rdf_alg(&rdf, str);
302825eb42bSJan Lentfer break;
303825eb42bSJan Lentfer case LDNS_RDF_TYPE_UNKNOWN:
304825eb42bSJan Lentfer status = ldns_str2rdf_unknown(&rdf, str);
305825eb42bSJan Lentfer break;
306825eb42bSJan Lentfer case LDNS_RDF_TYPE_TIME:
307825eb42bSJan Lentfer status = ldns_str2rdf_time(&rdf, str);
308825eb42bSJan Lentfer break;
309825eb42bSJan Lentfer case LDNS_RDF_TYPE_PERIOD:
310825eb42bSJan Lentfer status = ldns_str2rdf_period(&rdf, str);
311825eb42bSJan Lentfer break;
3125340022aSzrj case LDNS_RDF_TYPE_HIP:
3135340022aSzrj status = ldns_str2rdf_hip(&rdf, str);
314825eb42bSJan Lentfer break;
315825eb42bSJan Lentfer case LDNS_RDF_TYPE_SERVICE:
316825eb42bSJan Lentfer status = ldns_str2rdf_service(&rdf, str);
317825eb42bSJan Lentfer break;
318825eb42bSJan Lentfer case LDNS_RDF_TYPE_LOC:
319825eb42bSJan Lentfer status = ldns_str2rdf_loc(&rdf, str);
320825eb42bSJan Lentfer break;
321825eb42bSJan Lentfer case LDNS_RDF_TYPE_WKS:
322825eb42bSJan Lentfer status = ldns_str2rdf_wks(&rdf, str);
323825eb42bSJan Lentfer break;
324825eb42bSJan Lentfer case LDNS_RDF_TYPE_NSAP:
325825eb42bSJan Lentfer status = ldns_str2rdf_nsap(&rdf, str);
326825eb42bSJan Lentfer break;
327825eb42bSJan Lentfer case LDNS_RDF_TYPE_ATMA:
328825eb42bSJan Lentfer status = ldns_str2rdf_atma(&rdf, str);
329825eb42bSJan Lentfer break;
330825eb42bSJan Lentfer case LDNS_RDF_TYPE_IPSECKEY:
331825eb42bSJan Lentfer status = ldns_str2rdf_ipseckey(&rdf, str);
332825eb42bSJan Lentfer break;
333825eb42bSJan Lentfer case LDNS_RDF_TYPE_NSEC3_SALT:
334825eb42bSJan Lentfer status = ldns_str2rdf_nsec3_salt(&rdf, str);
335825eb42bSJan Lentfer break;
336825eb42bSJan Lentfer case LDNS_RDF_TYPE_NSEC3_NEXT_OWNER:
337825eb42bSJan Lentfer status = ldns_str2rdf_b32_ext(&rdf, str);
338825eb42bSJan Lentfer break;
3395340022aSzrj case LDNS_RDF_TYPE_ILNP64:
3405340022aSzrj status = ldns_str2rdf_ilnp64(&rdf, str);
3415340022aSzrj break;
3425340022aSzrj case LDNS_RDF_TYPE_EUI48:
3435340022aSzrj status = ldns_str2rdf_eui48(&rdf, str);
3445340022aSzrj break;
3455340022aSzrj case LDNS_RDF_TYPE_EUI64:
3465340022aSzrj status = ldns_str2rdf_eui64(&rdf, str);
3475340022aSzrj break;
3485340022aSzrj case LDNS_RDF_TYPE_TAG:
3495340022aSzrj status = ldns_str2rdf_tag(&rdf, str);
3505340022aSzrj break;
3515340022aSzrj case LDNS_RDF_TYPE_LONG_STR:
3525340022aSzrj status = ldns_str2rdf_long_str(&rdf, str);
3535340022aSzrj break;
3545340022aSzrj case LDNS_RDF_TYPE_CERTIFICATE_USAGE:
3555340022aSzrj status = ldns_str2rdf_certificate_usage(&rdf, str);
3565340022aSzrj break;
3575340022aSzrj case LDNS_RDF_TYPE_SELECTOR:
3585340022aSzrj status = ldns_str2rdf_selector(&rdf, str);
3595340022aSzrj break;
3605340022aSzrj case LDNS_RDF_TYPE_MATCHING_TYPE:
3615340022aSzrj status = ldns_str2rdf_matching_type(&rdf, str);
3625340022aSzrj break;
363819dec71SDaniel Fojt case LDNS_RDF_TYPE_AMTRELAY:
364819dec71SDaniel Fojt status = ldns_str2rdf_amtrelay(&rdf, str);
365819dec71SDaniel Fojt break;
366*ee791febSAntonio Huete Jimenez case LDNS_RDF_TYPE_SVCPARAMS:
367*ee791febSAntonio Huete Jimenez status = ldns_str2rdf_svcparams(&rdf, str);
368*ee791febSAntonio Huete Jimenez break;
369825eb42bSJan Lentfer case LDNS_RDF_TYPE_NONE:
370825eb42bSJan Lentfer default:
371825eb42bSJan Lentfer /* default default ??? */
372825eb42bSJan Lentfer status = LDNS_STATUS_ERR;
373825eb42bSJan Lentfer break;
374825eb42bSJan Lentfer }
375825eb42bSJan Lentfer if (LDNS_STATUS_OK == status) {
376825eb42bSJan Lentfer ldns_rdf_set_type(rdf, type);
377825eb42bSJan Lentfer return rdf;
378825eb42bSJan Lentfer }
379825eb42bSJan Lentfer if (rdf) {
380825eb42bSJan Lentfer LDNS_FREE(rdf);
381825eb42bSJan Lentfer }
382825eb42bSJan Lentfer return NULL;
383825eb42bSJan Lentfer }
384825eb42bSJan Lentfer
385825eb42bSJan Lentfer ldns_status
ldns_rdf_new_frm_fp(ldns_rdf ** rdf,ldns_rdf_type type,FILE * fp)386825eb42bSJan Lentfer ldns_rdf_new_frm_fp(ldns_rdf **rdf, ldns_rdf_type type, FILE *fp)
387825eb42bSJan Lentfer {
388825eb42bSJan Lentfer return ldns_rdf_new_frm_fp_l(rdf, type, fp, NULL);
389825eb42bSJan Lentfer }
390825eb42bSJan Lentfer
391825eb42bSJan Lentfer ldns_status
ldns_rdf_new_frm_fp_l(ldns_rdf ** rdf,ldns_rdf_type type,FILE * fp,int * line_nr)392825eb42bSJan Lentfer ldns_rdf_new_frm_fp_l(ldns_rdf **rdf, ldns_rdf_type type, FILE *fp, int *line_nr)
393825eb42bSJan Lentfer {
394825eb42bSJan Lentfer char *line;
395825eb42bSJan Lentfer ldns_rdf *r;
396825eb42bSJan Lentfer ssize_t t;
397825eb42bSJan Lentfer
398825eb42bSJan Lentfer line = LDNS_XMALLOC(char, LDNS_MAX_LINELEN + 1);
399825eb42bSJan Lentfer if (!line) {
400825eb42bSJan Lentfer return LDNS_STATUS_MEM_ERR;
401825eb42bSJan Lentfer }
402825eb42bSJan Lentfer
403825eb42bSJan Lentfer /* read an entire line in from the file */
404ac996e71SJan Lentfer if ((t = ldns_fget_token_l(fp, line, LDNS_PARSE_SKIP_SPACE, 0, line_nr)) == -1 || t == 0) {
405825eb42bSJan Lentfer LDNS_FREE(line);
406825eb42bSJan Lentfer return LDNS_STATUS_SYNTAX_RDATA_ERR;
407825eb42bSJan Lentfer }
408825eb42bSJan Lentfer r = ldns_rdf_new_frm_str(type, (const char*) line);
409825eb42bSJan Lentfer LDNS_FREE(line);
410825eb42bSJan Lentfer if (rdf) {
411825eb42bSJan Lentfer *rdf = r;
412825eb42bSJan Lentfer return LDNS_STATUS_OK;
413825eb42bSJan Lentfer } else {
414825eb42bSJan Lentfer return LDNS_STATUS_NULL;
415825eb42bSJan Lentfer }
416825eb42bSJan Lentfer }
417825eb42bSJan Lentfer
418825eb42bSJan Lentfer ldns_rdf *
ldns_rdf_address_reverse(const ldns_rdf * rd)4195340022aSzrj ldns_rdf_address_reverse(const ldns_rdf *rd)
420825eb42bSJan Lentfer {
421825eb42bSJan Lentfer uint8_t buf_4[LDNS_IP4ADDRLEN];
422825eb42bSJan Lentfer uint8_t buf_6[LDNS_IP6ADDRLEN * 2];
423825eb42bSJan Lentfer ldns_rdf *rev;
424825eb42bSJan Lentfer ldns_rdf *in_addr;
425825eb42bSJan Lentfer ldns_rdf *ret_dname;
426825eb42bSJan Lentfer uint8_t octet;
427825eb42bSJan Lentfer uint8_t nnibble;
428825eb42bSJan Lentfer uint8_t nibble;
429825eb42bSJan Lentfer uint8_t i, j;
430825eb42bSJan Lentfer
431825eb42bSJan Lentfer char *char_dname;
432825eb42bSJan Lentfer int nbit;
433825eb42bSJan Lentfer
434825eb42bSJan Lentfer if (ldns_rdf_get_type(rd) != LDNS_RDF_TYPE_A &&
435825eb42bSJan Lentfer ldns_rdf_get_type(rd) != LDNS_RDF_TYPE_AAAA) {
436825eb42bSJan Lentfer return NULL;
437825eb42bSJan Lentfer }
438825eb42bSJan Lentfer
439825eb42bSJan Lentfer in_addr = NULL;
440825eb42bSJan Lentfer ret_dname = NULL;
441825eb42bSJan Lentfer
442825eb42bSJan Lentfer switch(ldns_rdf_get_type(rd)) {
443825eb42bSJan Lentfer case LDNS_RDF_TYPE_A:
444825eb42bSJan Lentfer /* the length of the buffer is 4 */
445825eb42bSJan Lentfer buf_4[3] = ldns_rdf_data(rd)[0];
446825eb42bSJan Lentfer buf_4[2] = ldns_rdf_data(rd)[1];
447825eb42bSJan Lentfer buf_4[1] = ldns_rdf_data(rd)[2];
448825eb42bSJan Lentfer buf_4[0] = ldns_rdf_data(rd)[3];
449825eb42bSJan Lentfer in_addr = ldns_dname_new_frm_str("in-addr.arpa.");
450825eb42bSJan Lentfer if (!in_addr) {
451825eb42bSJan Lentfer return NULL;
452825eb42bSJan Lentfer }
453825eb42bSJan Lentfer /* make a new rdf and convert that back */
454825eb42bSJan Lentfer rev = ldns_rdf_new_frm_data( LDNS_RDF_TYPE_A,
455825eb42bSJan Lentfer LDNS_IP4ADDRLEN, (void*)&buf_4);
456825eb42bSJan Lentfer if (!rev) {
457825eb42bSJan Lentfer LDNS_FREE(in_addr);
458825eb42bSJan Lentfer return NULL;
459825eb42bSJan Lentfer }
460825eb42bSJan Lentfer
461825eb42bSJan Lentfer /* convert rev to a string */
462825eb42bSJan Lentfer char_dname = ldns_rdf2str(rev);
463825eb42bSJan Lentfer if (!char_dname) {
464825eb42bSJan Lentfer LDNS_FREE(in_addr);
465825eb42bSJan Lentfer ldns_rdf_deep_free(rev);
466825eb42bSJan Lentfer return NULL;
467825eb42bSJan Lentfer }
468825eb42bSJan Lentfer /* transform back to rdf with type dname */
469825eb42bSJan Lentfer ret_dname = ldns_dname_new_frm_str(char_dname);
470825eb42bSJan Lentfer if (!ret_dname) {
471825eb42bSJan Lentfer LDNS_FREE(in_addr);
472825eb42bSJan Lentfer ldns_rdf_deep_free(rev);
473825eb42bSJan Lentfer LDNS_FREE(char_dname);
474825eb42bSJan Lentfer return NULL;
475825eb42bSJan Lentfer }
476825eb42bSJan Lentfer /* not needed anymore */
477825eb42bSJan Lentfer ldns_rdf_deep_free(rev);
478825eb42bSJan Lentfer LDNS_FREE(char_dname);
479825eb42bSJan Lentfer break;
480825eb42bSJan Lentfer case LDNS_RDF_TYPE_AAAA:
481825eb42bSJan Lentfer /* some foo magic to reverse the nibbles ... */
482825eb42bSJan Lentfer
483825eb42bSJan Lentfer for (nbit = 127; nbit >= 0; nbit = nbit - 4) {
4845340022aSzrj /* calculate octet (8 bit) */
485825eb42bSJan Lentfer octet = ( ((unsigned int) nbit) & 0x78) >> 3;
486825eb42bSJan Lentfer /* calculate nibble */
487825eb42bSJan Lentfer nnibble = ( ((unsigned int) nbit) & 0x04) >> 2;
488825eb42bSJan Lentfer /* extract nibble */
489825eb42bSJan Lentfer nibble = (ldns_rdf_data(rd)[octet] & ( 0xf << (4 * (1 -
490825eb42bSJan Lentfer nnibble)) ) ) >> ( 4 * (1 -
491825eb42bSJan Lentfer nnibble));
492825eb42bSJan Lentfer
493825eb42bSJan Lentfer buf_6[(LDNS_IP6ADDRLEN * 2 - 1) -
494825eb42bSJan Lentfer (octet * 2 + nnibble)] =
495825eb42bSJan Lentfer (uint8_t)ldns_int_to_hexdigit((int)nibble);
496825eb42bSJan Lentfer }
497825eb42bSJan Lentfer
498825eb42bSJan Lentfer char_dname = LDNS_XMALLOC(char, (LDNS_IP6ADDRLEN * 4));
499825eb42bSJan Lentfer if (!char_dname) {
500825eb42bSJan Lentfer return NULL;
501825eb42bSJan Lentfer }
502825eb42bSJan Lentfer char_dname[LDNS_IP6ADDRLEN * 4 - 1] = '\0'; /* closure */
503825eb42bSJan Lentfer
504825eb42bSJan Lentfer /* walk the string and add . 's */
505825eb42bSJan Lentfer for (i = 0, j = 0; i < LDNS_IP6ADDRLEN * 2; i++, j = j + 2) {
506825eb42bSJan Lentfer char_dname[j] = (char)buf_6[i];
507825eb42bSJan Lentfer if (i != LDNS_IP6ADDRLEN * 2 - 1) {
508825eb42bSJan Lentfer char_dname[j + 1] = '.';
509825eb42bSJan Lentfer }
510825eb42bSJan Lentfer }
511825eb42bSJan Lentfer in_addr = ldns_dname_new_frm_str("ip6.arpa.");
512825eb42bSJan Lentfer if (!in_addr) {
513825eb42bSJan Lentfer LDNS_FREE(char_dname);
514825eb42bSJan Lentfer return NULL;
515825eb42bSJan Lentfer }
516825eb42bSJan Lentfer
517825eb42bSJan Lentfer /* convert rev to a string */
518825eb42bSJan Lentfer ret_dname = ldns_dname_new_frm_str(char_dname);
519825eb42bSJan Lentfer LDNS_FREE(char_dname);
520825eb42bSJan Lentfer if (!ret_dname) {
521825eb42bSJan Lentfer ldns_rdf_deep_free(in_addr);
522825eb42bSJan Lentfer return NULL;
523825eb42bSJan Lentfer }
524825eb42bSJan Lentfer break;
525825eb42bSJan Lentfer default:
526825eb42bSJan Lentfer break;
527825eb42bSJan Lentfer }
528825eb42bSJan Lentfer /* add the suffix */
529825eb42bSJan Lentfer rev = ldns_dname_cat_clone(ret_dname, in_addr);
530825eb42bSJan Lentfer
531825eb42bSJan Lentfer ldns_rdf_deep_free(ret_dname);
532825eb42bSJan Lentfer ldns_rdf_deep_free(in_addr);
533825eb42bSJan Lentfer return rev;
534825eb42bSJan Lentfer }
535825eb42bSJan Lentfer
536825eb42bSJan Lentfer ldns_status
ldns_rdf_hip_get_alg_hit_pk(ldns_rdf * rdf,uint8_t * alg,uint8_t * hit_size,uint8_t ** hit,uint16_t * pk_size,uint8_t ** pk)5375340022aSzrj ldns_rdf_hip_get_alg_hit_pk(ldns_rdf *rdf, uint8_t* alg,
5385340022aSzrj uint8_t *hit_size, uint8_t** hit,
5395340022aSzrj uint16_t *pk_size, uint8_t** pk)
5405340022aSzrj {
5415340022aSzrj uint8_t *data;
5425340022aSzrj size_t rdf_size;
5435340022aSzrj
5445340022aSzrj if (! rdf || ! alg || ! hit || ! hit_size || ! pk || ! pk_size) {
5455340022aSzrj return LDNS_STATUS_INVALID_POINTER;
5465340022aSzrj } else if (ldns_rdf_get_type(rdf) != LDNS_RDF_TYPE_HIP) {
5475340022aSzrj return LDNS_STATUS_INVALID_RDF_TYPE;
5485340022aSzrj } else if ((rdf_size = ldns_rdf_size(rdf)) < 6) {
5495340022aSzrj return LDNS_STATUS_WIRE_RDATA_ERR;
5505340022aSzrj }
5515340022aSzrj data = ldns_rdf_data(rdf);
5525340022aSzrj *hit_size = data[0];
5535340022aSzrj *alg = data[1];
5545340022aSzrj *pk_size = ldns_read_uint16(data + 2);
5555340022aSzrj *hit = data + 4;
5565340022aSzrj *pk = data + 4 + *hit_size;
5575340022aSzrj if (*hit_size == 0 || *pk_size == 0 ||
5585340022aSzrj rdf_size < (size_t) *hit_size + *pk_size + 4) {
5595340022aSzrj return LDNS_STATUS_WIRE_RDATA_ERR;
5605340022aSzrj }
5615340022aSzrj return LDNS_STATUS_OK;
5625340022aSzrj }
5635340022aSzrj
5645340022aSzrj ldns_status
ldns_rdf_hip_new_frm_alg_hit_pk(ldns_rdf ** rdf,uint8_t alg,uint8_t hit_size,uint8_t * hit,uint16_t pk_size,uint8_t * pk)5655340022aSzrj ldns_rdf_hip_new_frm_alg_hit_pk(ldns_rdf** rdf, uint8_t alg,
5665340022aSzrj uint8_t hit_size, uint8_t *hit,
5675340022aSzrj uint16_t pk_size, uint8_t *pk)
5685340022aSzrj {
5695340022aSzrj uint8_t *data;
5705340022aSzrj
5715340022aSzrj if (! rdf) {
5725340022aSzrj return LDNS_STATUS_INVALID_POINTER;
5735340022aSzrj }
5745340022aSzrj if (4 + hit_size + pk_size > LDNS_MAX_RDFLEN) {
5755340022aSzrj return LDNS_STATUS_RDATA_OVERFLOW;
5765340022aSzrj }
5775340022aSzrj data = LDNS_XMALLOC(uint8_t, 4 + hit_size + pk_size);
5785340022aSzrj if (data == NULL) {
5795340022aSzrj return LDNS_STATUS_MEM_ERR;
5805340022aSzrj }
5815340022aSzrj data[0] = hit_size;
5825340022aSzrj data[1] = alg;
5835340022aSzrj ldns_write_uint16(data + 2, pk_size);
5845340022aSzrj memcpy(data + 4, hit, hit_size);
5855340022aSzrj memcpy(data + 4 + hit_size, pk, pk_size);
5865340022aSzrj *rdf = ldns_rdf_new(LDNS_RDF_TYPE_HIP, 4 + hit_size + pk_size, data);
5875340022aSzrj if (! *rdf) {
5885340022aSzrj LDNS_FREE(data);
5895340022aSzrj return LDNS_STATUS_MEM_ERR;
5905340022aSzrj }
5915340022aSzrj return LDNS_STATUS_OK;
5925340022aSzrj }
5935340022aSzrj
5945340022aSzrj ldns_status
ldns_octet(char * word,size_t * length)595825eb42bSJan Lentfer ldns_octet(char *word, size_t *length)
596825eb42bSJan Lentfer {
597825eb42bSJan Lentfer char *s;
598825eb42bSJan Lentfer char *p;
599825eb42bSJan Lentfer *length = 0;
600825eb42bSJan Lentfer
601825eb42bSJan Lentfer for (s = p = word; *s != '\0'; s++,p++) {
602825eb42bSJan Lentfer switch (*s) {
603825eb42bSJan Lentfer case '.':
604825eb42bSJan Lentfer if (s[1] == '.') {
605825eb42bSJan Lentfer return LDNS_STATUS_EMPTY_LABEL;
606825eb42bSJan Lentfer }
607825eb42bSJan Lentfer *p = *s;
608825eb42bSJan Lentfer (*length)++;
609825eb42bSJan Lentfer break;
610825eb42bSJan Lentfer case '\\':
611825eb42bSJan Lentfer if ('0' <= s[1] && s[1] <= '9' &&
612825eb42bSJan Lentfer '0' <= s[2] && s[2] <= '9' &&
613825eb42bSJan Lentfer '0' <= s[3] && s[3] <= '9') {
614825eb42bSJan Lentfer /* \DDD seen */
615825eb42bSJan Lentfer int val = ((s[1] - '0') * 100 +
616825eb42bSJan Lentfer (s[2] - '0') * 10 + (s[3] - '0'));
617825eb42bSJan Lentfer
618825eb42bSJan Lentfer if (0 <= val && val <= 255) {
619825eb42bSJan Lentfer /* this also handles \0 */
620825eb42bSJan Lentfer s += 3;
621825eb42bSJan Lentfer *p = val;
622825eb42bSJan Lentfer (*length)++;
623825eb42bSJan Lentfer } else {
624825eb42bSJan Lentfer return LDNS_STATUS_DDD_OVERFLOW;
625825eb42bSJan Lentfer }
626825eb42bSJan Lentfer } else {
627*ee791febSAntonio Huete Jimenez /* an escaped character, like \<space> ?
628825eb42bSJan Lentfer * remove the '\' keep the rest */
629825eb42bSJan Lentfer *p = *++s;
630825eb42bSJan Lentfer (*length)++;
631825eb42bSJan Lentfer }
632825eb42bSJan Lentfer break;
633825eb42bSJan Lentfer case '\"':
634825eb42bSJan Lentfer /* non quoted " Is either first or the last character in
635825eb42bSJan Lentfer * the string */
636825eb42bSJan Lentfer
637825eb42bSJan Lentfer *p = *++s; /* skip it */
638825eb42bSJan Lentfer (*length)++;
639825eb42bSJan Lentfer /* I'm not sure if this is needed in libdns... MG */
640825eb42bSJan Lentfer if ( *s == '\0' ) {
641825eb42bSJan Lentfer /* ok, it was the last one */
642825eb42bSJan Lentfer *p = '\0';
643825eb42bSJan Lentfer return LDNS_STATUS_OK;
644825eb42bSJan Lentfer }
645825eb42bSJan Lentfer break;
646825eb42bSJan Lentfer default:
647825eb42bSJan Lentfer *p = *s;
648825eb42bSJan Lentfer (*length)++;
649825eb42bSJan Lentfer break;
650825eb42bSJan Lentfer }
651825eb42bSJan Lentfer }
652825eb42bSJan Lentfer *p = '\0';
653825eb42bSJan Lentfer return LDNS_STATUS_OK;
654825eb42bSJan Lentfer }
655825eb42bSJan Lentfer
656825eb42bSJan Lentfer int
ldns_rdf_compare(const ldns_rdf * rd1,const ldns_rdf * rd2)657825eb42bSJan Lentfer ldns_rdf_compare(const ldns_rdf *rd1, const ldns_rdf *rd2)
658825eb42bSJan Lentfer {
659825eb42bSJan Lentfer uint16_t i1, i2, i;
660825eb42bSJan Lentfer uint8_t *d1, *d2;
661825eb42bSJan Lentfer
662825eb42bSJan Lentfer /* only when both are not NULL we can say anything about them */
663825eb42bSJan Lentfer if (!rd1 && !rd2) {
664825eb42bSJan Lentfer return 0;
665825eb42bSJan Lentfer }
666825eb42bSJan Lentfer if (!rd1 || !rd2) {
667825eb42bSJan Lentfer return -1;
668825eb42bSJan Lentfer }
669825eb42bSJan Lentfer i1 = ldns_rdf_size(rd1);
670825eb42bSJan Lentfer i2 = ldns_rdf_size(rd2);
671825eb42bSJan Lentfer
672825eb42bSJan Lentfer if (i1 < i2) {
673825eb42bSJan Lentfer return -1;
674825eb42bSJan Lentfer } else if (i1 > i2) {
675825eb42bSJan Lentfer return +1;
676825eb42bSJan Lentfer } else {
677825eb42bSJan Lentfer d1 = (uint8_t*)ldns_rdf_data(rd1);
678825eb42bSJan Lentfer d2 = (uint8_t*)ldns_rdf_data(rd2);
679825eb42bSJan Lentfer for(i = 0; i < i1; i++) {
680825eb42bSJan Lentfer if (d1[i] < d2[i]) {
681825eb42bSJan Lentfer return -1;
682825eb42bSJan Lentfer } else if (d1[i] > d2[i]) {
683825eb42bSJan Lentfer return +1;
684825eb42bSJan Lentfer }
685825eb42bSJan Lentfer }
686825eb42bSJan Lentfer }
687825eb42bSJan Lentfer return 0;
688825eb42bSJan Lentfer }
689825eb42bSJan Lentfer
690825eb42bSJan Lentfer uint32_t
ldns_str2period(const char * nptr,const char ** endptr)691825eb42bSJan Lentfer ldns_str2period(const char *nptr, const char **endptr)
692825eb42bSJan Lentfer {
693825eb42bSJan Lentfer int sign = 0;
694825eb42bSJan Lentfer uint32_t i = 0;
695825eb42bSJan Lentfer uint32_t seconds = 0;
696825eb42bSJan Lentfer
697825eb42bSJan Lentfer for(*endptr = nptr; **endptr; (*endptr)++) {
698825eb42bSJan Lentfer switch (**endptr) {
699825eb42bSJan Lentfer case ' ':
700825eb42bSJan Lentfer case '\t':
701825eb42bSJan Lentfer break;
702825eb42bSJan Lentfer case '-':
703825eb42bSJan Lentfer if(sign == 0) {
704825eb42bSJan Lentfer sign = -1;
705825eb42bSJan Lentfer } else {
706825eb42bSJan Lentfer return seconds;
707825eb42bSJan Lentfer }
708825eb42bSJan Lentfer break;
709825eb42bSJan Lentfer case '+':
710825eb42bSJan Lentfer if(sign == 0) {
711825eb42bSJan Lentfer sign = 1;
712825eb42bSJan Lentfer } else {
713825eb42bSJan Lentfer return seconds;
714825eb42bSJan Lentfer }
715825eb42bSJan Lentfer break;
716825eb42bSJan Lentfer case 's':
717825eb42bSJan Lentfer case 'S':
718825eb42bSJan Lentfer seconds += i;
719825eb42bSJan Lentfer i = 0;
720825eb42bSJan Lentfer break;
721825eb42bSJan Lentfer case 'm':
722825eb42bSJan Lentfer case 'M':
723825eb42bSJan Lentfer seconds += i * 60;
724825eb42bSJan Lentfer i = 0;
725825eb42bSJan Lentfer break;
726825eb42bSJan Lentfer case 'h':
727825eb42bSJan Lentfer case 'H':
728825eb42bSJan Lentfer seconds += i * 60 * 60;
729825eb42bSJan Lentfer i = 0;
730825eb42bSJan Lentfer break;
731825eb42bSJan Lentfer case 'd':
732825eb42bSJan Lentfer case 'D':
733825eb42bSJan Lentfer seconds += i * 60 * 60 * 24;
734825eb42bSJan Lentfer i = 0;
735825eb42bSJan Lentfer break;
736825eb42bSJan Lentfer case 'w':
737825eb42bSJan Lentfer case 'W':
738825eb42bSJan Lentfer seconds += i * 60 * 60 * 24 * 7;
739825eb42bSJan Lentfer i = 0;
740825eb42bSJan Lentfer break;
741825eb42bSJan Lentfer case '0':
742825eb42bSJan Lentfer case '1':
743825eb42bSJan Lentfer case '2':
744825eb42bSJan Lentfer case '3':
745825eb42bSJan Lentfer case '4':
746825eb42bSJan Lentfer case '5':
747825eb42bSJan Lentfer case '6':
748825eb42bSJan Lentfer case '7':
749825eb42bSJan Lentfer case '8':
750825eb42bSJan Lentfer case '9':
751825eb42bSJan Lentfer i *= 10;
752825eb42bSJan Lentfer i += (**endptr - '0');
753825eb42bSJan Lentfer break;
754825eb42bSJan Lentfer default:
755825eb42bSJan Lentfer seconds += i;
756825eb42bSJan Lentfer /* disregard signedness */
757825eb42bSJan Lentfer return seconds;
758825eb42bSJan Lentfer }
759825eb42bSJan Lentfer }
760825eb42bSJan Lentfer seconds += i;
761825eb42bSJan Lentfer /* disregard signedness */
762825eb42bSJan Lentfer return seconds;
763825eb42bSJan Lentfer }
764