xref: /freebsd/contrib/ldns/rdata.c (revision 5afab0e5e56fe90a378fb57249600e7924e1cab2)
17b5038d7SDag-Erling Smørgrav /*
27b5038d7SDag-Erling Smørgrav  * rdata.c
37b5038d7SDag-Erling Smørgrav  *
47b5038d7SDag-Erling Smørgrav  * rdata implementation
57b5038d7SDag-Erling Smørgrav  *
67b5038d7SDag-Erling Smørgrav  * a Net::DNS like library for C
77b5038d7SDag-Erling Smørgrav  *
87b5038d7SDag-Erling Smørgrav  * (c) NLnet Labs, 2004-2006
97b5038d7SDag-Erling Smørgrav  *
107b5038d7SDag-Erling Smørgrav  * See the file LICENSE for the license
117b5038d7SDag-Erling Smørgrav  */
127b5038d7SDag-Erling Smørgrav 
137b5038d7SDag-Erling Smørgrav #include <ldns/config.h>
147b5038d7SDag-Erling Smørgrav 
157b5038d7SDag-Erling Smørgrav #include <ldns/ldns.h>
167b5038d7SDag-Erling Smørgrav 
177b5038d7SDag-Erling Smørgrav /*
187b5038d7SDag-Erling Smørgrav  * Access functions
197b5038d7SDag-Erling Smørgrav  * do this as functions to get type checking
207b5038d7SDag-Erling Smørgrav  */
217b5038d7SDag-Erling Smørgrav 
227b5038d7SDag-Erling Smørgrav /* read */
237b5038d7SDag-Erling Smørgrav size_t
ldns_rdf_size(const ldns_rdf * rd)247b5038d7SDag-Erling Smørgrav ldns_rdf_size(const ldns_rdf *rd)
257b5038d7SDag-Erling Smørgrav {
267b5038d7SDag-Erling Smørgrav 	assert(rd != NULL);
277b5038d7SDag-Erling Smørgrav 	return rd->_size;
287b5038d7SDag-Erling Smørgrav }
297b5038d7SDag-Erling Smørgrav 
307b5038d7SDag-Erling Smørgrav ldns_rdf_type
ldns_rdf_get_type(const ldns_rdf * rd)317b5038d7SDag-Erling Smørgrav ldns_rdf_get_type(const ldns_rdf *rd)
327b5038d7SDag-Erling Smørgrav {
337b5038d7SDag-Erling Smørgrav 	assert(rd != NULL);
347b5038d7SDag-Erling Smørgrav 	return rd->_type;
357b5038d7SDag-Erling Smørgrav }
367b5038d7SDag-Erling Smørgrav 
377b5038d7SDag-Erling Smørgrav uint8_t *
ldns_rdf_data(const ldns_rdf * rd)387b5038d7SDag-Erling Smørgrav ldns_rdf_data(const ldns_rdf *rd)
397b5038d7SDag-Erling Smørgrav {
407b5038d7SDag-Erling Smørgrav 	assert(rd != NULL);
417b5038d7SDag-Erling Smørgrav 	return rd->_data;
427b5038d7SDag-Erling Smørgrav }
437b5038d7SDag-Erling Smørgrav 
447b5038d7SDag-Erling Smørgrav /* write */
457b5038d7SDag-Erling Smørgrav void
ldns_rdf_set_size(ldns_rdf * rd,size_t size)467b5038d7SDag-Erling Smørgrav ldns_rdf_set_size(ldns_rdf *rd, size_t size)
477b5038d7SDag-Erling Smørgrav {
487b5038d7SDag-Erling Smørgrav 	assert(rd != NULL);
497b5038d7SDag-Erling Smørgrav 	rd->_size = size;
507b5038d7SDag-Erling Smørgrav }
517b5038d7SDag-Erling Smørgrav 
527b5038d7SDag-Erling Smørgrav void
ldns_rdf_set_type(ldns_rdf * rd,ldns_rdf_type type)537b5038d7SDag-Erling Smørgrav ldns_rdf_set_type(ldns_rdf *rd, ldns_rdf_type type)
547b5038d7SDag-Erling Smørgrav {
557b5038d7SDag-Erling Smørgrav 	assert(rd != NULL);
567b5038d7SDag-Erling Smørgrav 	rd->_type = type;
577b5038d7SDag-Erling Smørgrav }
587b5038d7SDag-Erling Smørgrav 
597b5038d7SDag-Erling Smørgrav void
ldns_rdf_set_data(ldns_rdf * rd,void * data)607b5038d7SDag-Erling Smørgrav ldns_rdf_set_data(ldns_rdf *rd, void *data)
617b5038d7SDag-Erling Smørgrav {
627b5038d7SDag-Erling Smørgrav 	/* only copy the pointer */
637b5038d7SDag-Erling Smørgrav 	assert(rd != NULL);
647b5038d7SDag-Erling Smørgrav 	rd->_data = data;
657b5038d7SDag-Erling Smørgrav }
667b5038d7SDag-Erling Smørgrav 
677b5038d7SDag-Erling Smørgrav /* for types that allow it, return
687b5038d7SDag-Erling Smørgrav  * the native/host order type */
697b5038d7SDag-Erling Smørgrav uint8_t
ldns_rdf2native_int8(const ldns_rdf * rd)707b5038d7SDag-Erling Smørgrav ldns_rdf2native_int8(const ldns_rdf *rd)
717b5038d7SDag-Erling Smørgrav {
727b5038d7SDag-Erling Smørgrav 	uint8_t data;
737b5038d7SDag-Erling Smørgrav 
747b5038d7SDag-Erling Smørgrav 	/* only allow 8 bit rdfs */
757b5038d7SDag-Erling Smørgrav 	if (ldns_rdf_size(rd) != LDNS_RDF_SIZE_BYTE) {
767b5038d7SDag-Erling Smørgrav 		return 0;
777b5038d7SDag-Erling Smørgrav 	}
787b5038d7SDag-Erling Smørgrav 
797b5038d7SDag-Erling Smørgrav 	memcpy(&data, ldns_rdf_data(rd), sizeof(data));
807b5038d7SDag-Erling Smørgrav 	return data;
817b5038d7SDag-Erling Smørgrav }
827b5038d7SDag-Erling Smørgrav 
837b5038d7SDag-Erling Smørgrav uint16_t
ldns_rdf2native_int16(const ldns_rdf * rd)847b5038d7SDag-Erling Smørgrav ldns_rdf2native_int16(const ldns_rdf *rd)
857b5038d7SDag-Erling Smørgrav {
867b5038d7SDag-Erling Smørgrav 	uint16_t data;
877b5038d7SDag-Erling Smørgrav 
887b5038d7SDag-Erling Smørgrav 	/* only allow 16 bit rdfs */
897b5038d7SDag-Erling Smørgrav 	if (ldns_rdf_size(rd) != LDNS_RDF_SIZE_WORD) {
907b5038d7SDag-Erling Smørgrav 		return 0;
917b5038d7SDag-Erling Smørgrav 	}
927b5038d7SDag-Erling Smørgrav 
937b5038d7SDag-Erling Smørgrav 	memcpy(&data, ldns_rdf_data(rd), sizeof(data));
947b5038d7SDag-Erling Smørgrav 	return ntohs(data);
957b5038d7SDag-Erling Smørgrav }
967b5038d7SDag-Erling Smørgrav 
977b5038d7SDag-Erling Smørgrav uint32_t
ldns_rdf2native_int32(const ldns_rdf * rd)987b5038d7SDag-Erling Smørgrav ldns_rdf2native_int32(const ldns_rdf *rd)
997b5038d7SDag-Erling Smørgrav {
1007b5038d7SDag-Erling Smørgrav 	uint32_t data;
1017b5038d7SDag-Erling Smørgrav 
1027b5038d7SDag-Erling Smørgrav 	/* only allow 32 bit rdfs */
1037b5038d7SDag-Erling Smørgrav 	if (ldns_rdf_size(rd) != LDNS_RDF_SIZE_DOUBLEWORD) {
1047b5038d7SDag-Erling Smørgrav 		return 0;
1057b5038d7SDag-Erling Smørgrav 	}
1067b5038d7SDag-Erling Smørgrav 
1077b5038d7SDag-Erling Smørgrav 	memcpy(&data, ldns_rdf_data(rd), sizeof(data));
1087b5038d7SDag-Erling Smørgrav 	return ntohl(data);
1097b5038d7SDag-Erling Smørgrav }
1107b5038d7SDag-Erling Smørgrav 
1117b5038d7SDag-Erling Smørgrav time_t
ldns_rdf2native_time_t(const ldns_rdf * rd)1127b5038d7SDag-Erling Smørgrav ldns_rdf2native_time_t(const ldns_rdf *rd)
1137b5038d7SDag-Erling Smørgrav {
1147b5038d7SDag-Erling Smørgrav 	uint32_t data;
1157b5038d7SDag-Erling Smørgrav 
11617d15b25SDag-Erling Smørgrav 	/* only allow 32 bit rdfs */
11717d15b25SDag-Erling Smørgrav 	if (ldns_rdf_size(rd) != LDNS_RDF_SIZE_DOUBLEWORD ||
11817d15b25SDag-Erling Smørgrav 			ldns_rdf_get_type(rd) != LDNS_RDF_TYPE_TIME) {
1197b5038d7SDag-Erling Smørgrav 		return 0;
1207b5038d7SDag-Erling Smørgrav 	}
12117d15b25SDag-Erling Smørgrav 	memcpy(&data, ldns_rdf_data(rd), sizeof(data));
12217d15b25SDag-Erling Smørgrav 	return (time_t)ntohl(data);
1237b5038d7SDag-Erling Smørgrav }
1247b5038d7SDag-Erling Smørgrav 
1257b5038d7SDag-Erling Smørgrav ldns_rdf *
ldns_native2rdf_int8(ldns_rdf_type type,uint8_t value)1267b5038d7SDag-Erling Smørgrav ldns_native2rdf_int8(ldns_rdf_type type, uint8_t value)
1277b5038d7SDag-Erling Smørgrav {
1287b5038d7SDag-Erling Smørgrav 	return ldns_rdf_new_frm_data(type, LDNS_RDF_SIZE_BYTE, &value);
1297b5038d7SDag-Erling Smørgrav }
1307b5038d7SDag-Erling Smørgrav 
1317b5038d7SDag-Erling Smørgrav ldns_rdf *
ldns_native2rdf_int16(ldns_rdf_type type,uint16_t value)1327b5038d7SDag-Erling Smørgrav ldns_native2rdf_int16(ldns_rdf_type type, uint16_t value)
1337b5038d7SDag-Erling Smørgrav {
1347b5038d7SDag-Erling Smørgrav 	uint16_t *rdf_data = LDNS_XMALLOC(uint16_t, 1);
1357b5038d7SDag-Erling Smørgrav         ldns_rdf* rdf;
1367b5038d7SDag-Erling Smørgrav 	if (!rdf_data) {
1377b5038d7SDag-Erling Smørgrav 		return NULL;
1387b5038d7SDag-Erling Smørgrav 	}
1397b5038d7SDag-Erling Smørgrav 	ldns_write_uint16(rdf_data, value);
1407b5038d7SDag-Erling Smørgrav 	rdf = ldns_rdf_new(type, LDNS_RDF_SIZE_WORD, rdf_data);
1417b5038d7SDag-Erling Smørgrav         if(!rdf)
1427b5038d7SDag-Erling Smørgrav                 LDNS_FREE(rdf_data);
1437b5038d7SDag-Erling Smørgrav         return rdf;
1447b5038d7SDag-Erling Smørgrav }
1457b5038d7SDag-Erling Smørgrav 
1467b5038d7SDag-Erling Smørgrav ldns_rdf *
ldns_native2rdf_int32(ldns_rdf_type type,uint32_t value)1477b5038d7SDag-Erling Smørgrav ldns_native2rdf_int32(ldns_rdf_type type, uint32_t value)
1487b5038d7SDag-Erling Smørgrav {
1497b5038d7SDag-Erling Smørgrav 	uint32_t *rdf_data = LDNS_XMALLOC(uint32_t, 1);
1507b5038d7SDag-Erling Smørgrav         ldns_rdf* rdf;
1517b5038d7SDag-Erling Smørgrav 	if (!rdf_data) {
1527b5038d7SDag-Erling Smørgrav 		return NULL;
1537b5038d7SDag-Erling Smørgrav 	}
1547b5038d7SDag-Erling Smørgrav 	ldns_write_uint32(rdf_data, value);
1557b5038d7SDag-Erling Smørgrav 	rdf = ldns_rdf_new(type, LDNS_RDF_SIZE_DOUBLEWORD, rdf_data);
1567b5038d7SDag-Erling Smørgrav         if(!rdf)
1577b5038d7SDag-Erling Smørgrav                 LDNS_FREE(rdf_data);
1587b5038d7SDag-Erling Smørgrav         return rdf;
1597b5038d7SDag-Erling Smørgrav }
1607b5038d7SDag-Erling Smørgrav 
1617b5038d7SDag-Erling Smørgrav ldns_rdf *
ldns_native2rdf_int16_data(size_t size,uint8_t * data)1627b5038d7SDag-Erling Smørgrav ldns_native2rdf_int16_data(size_t size, uint8_t *data)
1637b5038d7SDag-Erling Smørgrav {
1647b5038d7SDag-Erling Smørgrav 	uint8_t *rdf_data = LDNS_XMALLOC(uint8_t, size + 2);
1657b5038d7SDag-Erling Smørgrav         ldns_rdf* rdf;
1667b5038d7SDag-Erling Smørgrav 	if (!rdf_data) {
1677b5038d7SDag-Erling Smørgrav 		return NULL;
1687b5038d7SDag-Erling Smørgrav 	}
1697b5038d7SDag-Erling Smørgrav 	ldns_write_uint16(rdf_data, size);
1707b5038d7SDag-Erling Smørgrav 	memcpy(rdf_data + 2, data, size);
1717b5038d7SDag-Erling Smørgrav 	rdf = ldns_rdf_new(LDNS_RDF_TYPE_INT16_DATA, size + 2, rdf_data);
1727b5038d7SDag-Erling Smørgrav         if(!rdf)
1737b5038d7SDag-Erling Smørgrav                 LDNS_FREE(rdf_data);
1747b5038d7SDag-Erling Smørgrav         return rdf;
1757b5038d7SDag-Erling Smørgrav }
1767b5038d7SDag-Erling Smørgrav 
1777b5038d7SDag-Erling Smørgrav /* note: data must be allocated memory */
1787b5038d7SDag-Erling Smørgrav ldns_rdf *
ldns_rdf_new(ldns_rdf_type type,size_t size,void * data)1797b5038d7SDag-Erling Smørgrav ldns_rdf_new(ldns_rdf_type type, size_t size, void *data)
1807b5038d7SDag-Erling Smørgrav {
1817b5038d7SDag-Erling Smørgrav 	ldns_rdf *rd;
1827b5038d7SDag-Erling Smørgrav 	rd = LDNS_MALLOC(ldns_rdf);
1837b5038d7SDag-Erling Smørgrav 	if (!rd) {
1847b5038d7SDag-Erling Smørgrav 		return NULL;
1857b5038d7SDag-Erling Smørgrav 	}
1867b5038d7SDag-Erling Smørgrav 	ldns_rdf_set_size(rd, size);
1877b5038d7SDag-Erling Smørgrav 	ldns_rdf_set_type(rd, type);
1887b5038d7SDag-Erling Smørgrav 	ldns_rdf_set_data(rd, data);
1897b5038d7SDag-Erling Smørgrav 	return rd;
1907b5038d7SDag-Erling Smørgrav }
1917b5038d7SDag-Erling Smørgrav 
1927b5038d7SDag-Erling Smørgrav ldns_rdf *
ldns_rdf_new_frm_data(ldns_rdf_type type,size_t size,const void * data)1937b5038d7SDag-Erling Smørgrav ldns_rdf_new_frm_data(ldns_rdf_type type, size_t size, const void *data)
1947b5038d7SDag-Erling Smørgrav {
1957b5038d7SDag-Erling Smørgrav 	ldns_rdf *rdf;
1967b5038d7SDag-Erling Smørgrav 
1977b5038d7SDag-Erling Smørgrav 	/* if the size is too big, fail */
1987b5038d7SDag-Erling Smørgrav 	if (size > LDNS_MAX_RDFLEN) {
1997b5038d7SDag-Erling Smørgrav 		return NULL;
2007b5038d7SDag-Erling Smørgrav 	}
2017b5038d7SDag-Erling Smørgrav 
2027b5038d7SDag-Erling Smørgrav 	/* allocate space */
2037b5038d7SDag-Erling Smørgrav 	rdf = LDNS_MALLOC(ldns_rdf);
2047b5038d7SDag-Erling Smørgrav 	if (!rdf) {
2057b5038d7SDag-Erling Smørgrav 		return NULL;
2067b5038d7SDag-Erling Smørgrav 	}
2077b5038d7SDag-Erling Smørgrav 	rdf->_data = LDNS_XMALLOC(uint8_t, size);
2087b5038d7SDag-Erling Smørgrav 	if (!rdf->_data) {
2097b5038d7SDag-Erling Smørgrav 		LDNS_FREE(rdf);
2107b5038d7SDag-Erling Smørgrav 		return NULL;
2117b5038d7SDag-Erling Smørgrav 	}
2127b5038d7SDag-Erling Smørgrav 
2137b5038d7SDag-Erling Smørgrav 	/* set the values */
2147b5038d7SDag-Erling Smørgrav 	ldns_rdf_set_type(rdf, type);
2157b5038d7SDag-Erling Smørgrav 	ldns_rdf_set_size(rdf, size);
2167b5038d7SDag-Erling Smørgrav 	memcpy(rdf->_data, data, size);
2177b5038d7SDag-Erling Smørgrav 
2187b5038d7SDag-Erling Smørgrav 	return rdf;
2197b5038d7SDag-Erling Smørgrav }
2207b5038d7SDag-Erling Smørgrav 
2217b5038d7SDag-Erling Smørgrav ldns_rdf *
ldns_rdf_clone(const ldns_rdf * rd)2227b5038d7SDag-Erling Smørgrav ldns_rdf_clone(const ldns_rdf *rd)
2237b5038d7SDag-Erling Smørgrav {
2247b5038d7SDag-Erling Smørgrav 	assert(rd != NULL);
2257b5038d7SDag-Erling Smørgrav 	return (ldns_rdf_new_frm_data( ldns_rdf_get_type(rd),
2267b5038d7SDag-Erling Smørgrav 		ldns_rdf_size(rd), ldns_rdf_data(rd)));
2277b5038d7SDag-Erling Smørgrav }
2287b5038d7SDag-Erling Smørgrav 
2297b5038d7SDag-Erling Smørgrav void
ldns_rdf_deep_free(ldns_rdf * rd)2307b5038d7SDag-Erling Smørgrav ldns_rdf_deep_free(ldns_rdf *rd)
2317b5038d7SDag-Erling Smørgrav {
2327b5038d7SDag-Erling Smørgrav 	if (rd) {
2337b5038d7SDag-Erling Smørgrav 		if (rd->_data) {
2347b5038d7SDag-Erling Smørgrav 			LDNS_FREE(rd->_data);
2357b5038d7SDag-Erling Smørgrav 		}
2367b5038d7SDag-Erling Smørgrav 		LDNS_FREE(rd);
2377b5038d7SDag-Erling Smørgrav 	}
2387b5038d7SDag-Erling Smørgrav }
2397b5038d7SDag-Erling Smørgrav 
2407b5038d7SDag-Erling Smørgrav void
ldns_rdf_free(ldns_rdf * rd)2417b5038d7SDag-Erling Smørgrav ldns_rdf_free(ldns_rdf *rd)
2427b5038d7SDag-Erling Smørgrav {
2437b5038d7SDag-Erling Smørgrav 	if (rd) {
2447b5038d7SDag-Erling Smørgrav 		LDNS_FREE(rd);
2457b5038d7SDag-Erling Smørgrav 	}
2467b5038d7SDag-Erling Smørgrav }
2477b5038d7SDag-Erling Smørgrav 
2487b5038d7SDag-Erling Smørgrav ldns_rdf *
ldns_rdf_new_frm_str(ldns_rdf_type type,const char * str)2497b5038d7SDag-Erling Smørgrav ldns_rdf_new_frm_str(ldns_rdf_type type, const char *str)
2507b5038d7SDag-Erling Smørgrav {
2517b5038d7SDag-Erling Smørgrav 	ldns_rdf *rdf = NULL;
2527b5038d7SDag-Erling Smørgrav 	ldns_status status;
2537b5038d7SDag-Erling Smørgrav 
2547b5038d7SDag-Erling Smørgrav 	switch (type) {
2557b5038d7SDag-Erling Smørgrav 	case LDNS_RDF_TYPE_DNAME:
2567b5038d7SDag-Erling Smørgrav 		status = ldns_str2rdf_dname(&rdf, str);
2577b5038d7SDag-Erling Smørgrav 		break;
2587b5038d7SDag-Erling Smørgrav 	case LDNS_RDF_TYPE_INT8:
2597b5038d7SDag-Erling Smørgrav 		status = ldns_str2rdf_int8(&rdf, str);
2607b5038d7SDag-Erling Smørgrav 		break;
2617b5038d7SDag-Erling Smørgrav 	case LDNS_RDF_TYPE_INT16:
2627b5038d7SDag-Erling Smørgrav 		status = ldns_str2rdf_int16(&rdf, str);
2637b5038d7SDag-Erling Smørgrav 		break;
2647b5038d7SDag-Erling Smørgrav 	case LDNS_RDF_TYPE_INT32:
2657b5038d7SDag-Erling Smørgrav 		status = ldns_str2rdf_int32(&rdf, str);
2667b5038d7SDag-Erling Smørgrav 		break;
2677b5038d7SDag-Erling Smørgrav 	case LDNS_RDF_TYPE_A:
2687b5038d7SDag-Erling Smørgrav 		status = ldns_str2rdf_a(&rdf, str);
2697b5038d7SDag-Erling Smørgrav 		break;
2707b5038d7SDag-Erling Smørgrav 	case LDNS_RDF_TYPE_AAAA:
2717b5038d7SDag-Erling Smørgrav 		status = ldns_str2rdf_aaaa(&rdf, str);
2727b5038d7SDag-Erling Smørgrav 		break;
2737b5038d7SDag-Erling Smørgrav 	case LDNS_RDF_TYPE_STR:
2747b5038d7SDag-Erling Smørgrav 		status = ldns_str2rdf_str(&rdf, str);
2757b5038d7SDag-Erling Smørgrav 		break;
2767b5038d7SDag-Erling Smørgrav 	case LDNS_RDF_TYPE_APL:
2777b5038d7SDag-Erling Smørgrav 		status = ldns_str2rdf_apl(&rdf, str);
2787b5038d7SDag-Erling Smørgrav 		break;
2797b5038d7SDag-Erling Smørgrav 	case LDNS_RDF_TYPE_B64:
2807b5038d7SDag-Erling Smørgrav 		status = ldns_str2rdf_b64(&rdf, str);
2817b5038d7SDag-Erling Smørgrav 		break;
2827b5038d7SDag-Erling Smørgrav 	case LDNS_RDF_TYPE_B32_EXT:
2837b5038d7SDag-Erling Smørgrav 		status = ldns_str2rdf_b32_ext(&rdf, str);
2847b5038d7SDag-Erling Smørgrav 		break;
2857b5038d7SDag-Erling Smørgrav 	case LDNS_RDF_TYPE_HEX:
2867b5038d7SDag-Erling Smørgrav 		status = ldns_str2rdf_hex(&rdf, str);
2877b5038d7SDag-Erling Smørgrav 		break;
2887b5038d7SDag-Erling Smørgrav 	case LDNS_RDF_TYPE_NSEC:
2897b5038d7SDag-Erling Smørgrav 		status = ldns_str2rdf_nsec(&rdf, str);
2907b5038d7SDag-Erling Smørgrav 		break;
2917b5038d7SDag-Erling Smørgrav 	case LDNS_RDF_TYPE_TYPE:
2927b5038d7SDag-Erling Smørgrav 		status = ldns_str2rdf_type(&rdf, str);
2937b5038d7SDag-Erling Smørgrav 		break;
2947b5038d7SDag-Erling Smørgrav 	case LDNS_RDF_TYPE_CLASS:
2957b5038d7SDag-Erling Smørgrav 		status = ldns_str2rdf_class(&rdf, str);
2967b5038d7SDag-Erling Smørgrav 		break;
2977b5038d7SDag-Erling Smørgrav 	case LDNS_RDF_TYPE_CERT_ALG:
2987b5038d7SDag-Erling Smørgrav 		status = ldns_str2rdf_cert_alg(&rdf, str);
2997b5038d7SDag-Erling Smørgrav 		break;
3007b5038d7SDag-Erling Smørgrav 	case LDNS_RDF_TYPE_ALG:
3017b5038d7SDag-Erling Smørgrav 		status = ldns_str2rdf_alg(&rdf, str);
3027b5038d7SDag-Erling Smørgrav 		break;
3037b5038d7SDag-Erling Smørgrav 	case LDNS_RDF_TYPE_UNKNOWN:
3047b5038d7SDag-Erling Smørgrav 		status = ldns_str2rdf_unknown(&rdf, str);
3057b5038d7SDag-Erling Smørgrav 		break;
3067b5038d7SDag-Erling Smørgrav 	case LDNS_RDF_TYPE_TIME:
3077b5038d7SDag-Erling Smørgrav 		status = ldns_str2rdf_time(&rdf, str);
3087b5038d7SDag-Erling Smørgrav 		break;
3097b5038d7SDag-Erling Smørgrav 	case LDNS_RDF_TYPE_PERIOD:
3107b5038d7SDag-Erling Smørgrav 		status = ldns_str2rdf_period(&rdf, str);
3117b5038d7SDag-Erling Smørgrav 		break;
31217d15b25SDag-Erling Smørgrav 	case LDNS_RDF_TYPE_HIP:
31317d15b25SDag-Erling Smørgrav 		status = ldns_str2rdf_hip(&rdf, str);
3147b5038d7SDag-Erling Smørgrav 		break;
3157b5038d7SDag-Erling Smørgrav 	case LDNS_RDF_TYPE_SERVICE:
3167b5038d7SDag-Erling Smørgrav 		status = ldns_str2rdf_service(&rdf, str);
3177b5038d7SDag-Erling Smørgrav 		break;
3187b5038d7SDag-Erling Smørgrav 	case LDNS_RDF_TYPE_LOC:
3197b5038d7SDag-Erling Smørgrav 		status = ldns_str2rdf_loc(&rdf, str);
3207b5038d7SDag-Erling Smørgrav 		break;
3217b5038d7SDag-Erling Smørgrav 	case LDNS_RDF_TYPE_WKS:
3227b5038d7SDag-Erling Smørgrav 		status = ldns_str2rdf_wks(&rdf, str);
3237b5038d7SDag-Erling Smørgrav 		break;
3247b5038d7SDag-Erling Smørgrav 	case LDNS_RDF_TYPE_NSAP:
3257b5038d7SDag-Erling Smørgrav 		status = ldns_str2rdf_nsap(&rdf, str);
3267b5038d7SDag-Erling Smørgrav 		break;
3277b5038d7SDag-Erling Smørgrav 	case LDNS_RDF_TYPE_ATMA:
3287b5038d7SDag-Erling Smørgrav 		status = ldns_str2rdf_atma(&rdf, str);
3297b5038d7SDag-Erling Smørgrav 		break;
3307b5038d7SDag-Erling Smørgrav 	case LDNS_RDF_TYPE_IPSECKEY:
3317b5038d7SDag-Erling Smørgrav 		status = ldns_str2rdf_ipseckey(&rdf, str);
3327b5038d7SDag-Erling Smørgrav 		break;
3337b5038d7SDag-Erling Smørgrav 	case LDNS_RDF_TYPE_NSEC3_SALT:
3347b5038d7SDag-Erling Smørgrav 		status = ldns_str2rdf_nsec3_salt(&rdf, str);
3357b5038d7SDag-Erling Smørgrav 		break;
3367b5038d7SDag-Erling Smørgrav 	case LDNS_RDF_TYPE_NSEC3_NEXT_OWNER:
3377b5038d7SDag-Erling Smørgrav 		status = ldns_str2rdf_b32_ext(&rdf, str);
3387b5038d7SDag-Erling Smørgrav 		break;
33917d15b25SDag-Erling Smørgrav 	case LDNS_RDF_TYPE_ILNP64:
34017d15b25SDag-Erling Smørgrav 		status = ldns_str2rdf_ilnp64(&rdf, str);
34117d15b25SDag-Erling Smørgrav 		break;
34217d15b25SDag-Erling Smørgrav 	case LDNS_RDF_TYPE_EUI48:
34317d15b25SDag-Erling Smørgrav 		status = ldns_str2rdf_eui48(&rdf, str);
34417d15b25SDag-Erling Smørgrav 		break;
34517d15b25SDag-Erling Smørgrav 	case LDNS_RDF_TYPE_EUI64:
34617d15b25SDag-Erling Smørgrav 		status = ldns_str2rdf_eui64(&rdf, str);
34717d15b25SDag-Erling Smørgrav 		break;
34817d15b25SDag-Erling Smørgrav 	case LDNS_RDF_TYPE_TAG:
34917d15b25SDag-Erling Smørgrav 		status = ldns_str2rdf_tag(&rdf, str);
35017d15b25SDag-Erling Smørgrav 		break;
35117d15b25SDag-Erling Smørgrav 	case LDNS_RDF_TYPE_LONG_STR:
35217d15b25SDag-Erling Smørgrav 		status = ldns_str2rdf_long_str(&rdf, str);
35317d15b25SDag-Erling Smørgrav 		break;
354986ba33cSDag-Erling Smørgrav 	case LDNS_RDF_TYPE_CERTIFICATE_USAGE:
355986ba33cSDag-Erling Smørgrav 		status = ldns_str2rdf_certificate_usage(&rdf, str);
356986ba33cSDag-Erling Smørgrav 		break;
357986ba33cSDag-Erling Smørgrav 	case LDNS_RDF_TYPE_SELECTOR:
358986ba33cSDag-Erling Smørgrav 		status = ldns_str2rdf_selector(&rdf, str);
359986ba33cSDag-Erling Smørgrav 		break;
360986ba33cSDag-Erling Smørgrav 	case LDNS_RDF_TYPE_MATCHING_TYPE:
361986ba33cSDag-Erling Smørgrav 		status = ldns_str2rdf_matching_type(&rdf, str);
362986ba33cSDag-Erling Smørgrav 		break;
363*5afab0e5SDag-Erling Smørgrav 	case LDNS_RDF_TYPE_AMTRELAY:
364*5afab0e5SDag-Erling Smørgrav 		status = ldns_str2rdf_amtrelay(&rdf, str);
365*5afab0e5SDag-Erling Smørgrav 		break;
366*5afab0e5SDag-Erling Smørgrav 	case LDNS_RDF_TYPE_SVCPARAMS:
367*5afab0e5SDag-Erling Smørgrav 		status = ldns_str2rdf_svcparams(&rdf, str);
368*5afab0e5SDag-Erling Smørgrav 		break;
3697b5038d7SDag-Erling Smørgrav 	case LDNS_RDF_TYPE_NONE:
3707b5038d7SDag-Erling Smørgrav 	default:
3717b5038d7SDag-Erling Smørgrav 		/* default default ??? */
3727b5038d7SDag-Erling Smørgrav 		status = LDNS_STATUS_ERR;
3737b5038d7SDag-Erling Smørgrav 		break;
3747b5038d7SDag-Erling Smørgrav 	}
3757b5038d7SDag-Erling Smørgrav 	if (LDNS_STATUS_OK == status) {
3767b5038d7SDag-Erling Smørgrav 		ldns_rdf_set_type(rdf, type);
3777b5038d7SDag-Erling Smørgrav 		return rdf;
3787b5038d7SDag-Erling Smørgrav 	}
3797b5038d7SDag-Erling Smørgrav 	if (rdf) {
3807b5038d7SDag-Erling Smørgrav 		LDNS_FREE(rdf);
3817b5038d7SDag-Erling Smørgrav 	}
3827b5038d7SDag-Erling Smørgrav 	return NULL;
3837b5038d7SDag-Erling Smørgrav }
3847b5038d7SDag-Erling Smørgrav 
3857b5038d7SDag-Erling Smørgrav ldns_status
ldns_rdf_new_frm_fp(ldns_rdf ** rdf,ldns_rdf_type type,FILE * fp)3867b5038d7SDag-Erling Smørgrav ldns_rdf_new_frm_fp(ldns_rdf **rdf, ldns_rdf_type type, FILE *fp)
3877b5038d7SDag-Erling Smørgrav {
3887b5038d7SDag-Erling Smørgrav 	return ldns_rdf_new_frm_fp_l(rdf, type, fp, NULL);
3897b5038d7SDag-Erling Smørgrav }
3907b5038d7SDag-Erling Smørgrav 
3917b5038d7SDag-Erling Smørgrav ldns_status
ldns_rdf_new_frm_fp_l(ldns_rdf ** rdf,ldns_rdf_type type,FILE * fp,int * line_nr)3927b5038d7SDag-Erling Smørgrav ldns_rdf_new_frm_fp_l(ldns_rdf **rdf, ldns_rdf_type type, FILE *fp, int *line_nr)
3937b5038d7SDag-Erling Smørgrav {
3947b5038d7SDag-Erling Smørgrav 	char *line;
3957b5038d7SDag-Erling Smørgrav 	ldns_rdf *r;
3967b5038d7SDag-Erling Smørgrav 	ssize_t t;
3977b5038d7SDag-Erling Smørgrav 
3987b5038d7SDag-Erling Smørgrav 	line = LDNS_XMALLOC(char, LDNS_MAX_LINELEN + 1);
3997b5038d7SDag-Erling Smørgrav 	if (!line) {
4007b5038d7SDag-Erling Smørgrav 		return LDNS_STATUS_MEM_ERR;
4017b5038d7SDag-Erling Smørgrav 	}
4027b5038d7SDag-Erling Smørgrav 
4037b5038d7SDag-Erling Smørgrav 	/* read an entire line in from the file */
4047b5038d7SDag-Erling Smørgrav 	if ((t = ldns_fget_token_l(fp, line, LDNS_PARSE_SKIP_SPACE, 0, line_nr)) == -1 || t == 0) {
4057b5038d7SDag-Erling Smørgrav 		LDNS_FREE(line);
4067b5038d7SDag-Erling Smørgrav 		return LDNS_STATUS_SYNTAX_RDATA_ERR;
4077b5038d7SDag-Erling Smørgrav 	}
4087b5038d7SDag-Erling Smørgrav 	r =  ldns_rdf_new_frm_str(type, (const char*) line);
4097b5038d7SDag-Erling Smørgrav 	LDNS_FREE(line);
4107b5038d7SDag-Erling Smørgrav 	if (rdf) {
4117b5038d7SDag-Erling Smørgrav 		*rdf = r;
4127b5038d7SDag-Erling Smørgrav 		return LDNS_STATUS_OK;
4137b5038d7SDag-Erling Smørgrav 	} else {
4147b5038d7SDag-Erling Smørgrav 		return LDNS_STATUS_NULL;
4157b5038d7SDag-Erling Smørgrav 	}
4167b5038d7SDag-Erling Smørgrav }
4177b5038d7SDag-Erling Smørgrav 
4187b5038d7SDag-Erling Smørgrav ldns_rdf *
ldns_rdf_address_reverse(const ldns_rdf * rd)419986ba33cSDag-Erling Smørgrav ldns_rdf_address_reverse(const ldns_rdf *rd)
4207b5038d7SDag-Erling Smørgrav {
4217b5038d7SDag-Erling Smørgrav 	uint8_t buf_4[LDNS_IP4ADDRLEN];
4227b5038d7SDag-Erling Smørgrav 	uint8_t buf_6[LDNS_IP6ADDRLEN * 2];
4237b5038d7SDag-Erling Smørgrav 	ldns_rdf *rev;
4247b5038d7SDag-Erling Smørgrav 	ldns_rdf *in_addr;
4257b5038d7SDag-Erling Smørgrav 	ldns_rdf *ret_dname;
4267b5038d7SDag-Erling Smørgrav 	uint8_t octet;
4277b5038d7SDag-Erling Smørgrav 	uint8_t nnibble;
4287b5038d7SDag-Erling Smørgrav 	uint8_t nibble;
4297b5038d7SDag-Erling Smørgrav 	uint8_t i, j;
4307b5038d7SDag-Erling Smørgrav 
4317b5038d7SDag-Erling Smørgrav 	char *char_dname;
4327b5038d7SDag-Erling Smørgrav 	int nbit;
4337b5038d7SDag-Erling Smørgrav 
4347b5038d7SDag-Erling Smørgrav 	if (ldns_rdf_get_type(rd) != LDNS_RDF_TYPE_A &&
4357b5038d7SDag-Erling Smørgrav 			ldns_rdf_get_type(rd) != LDNS_RDF_TYPE_AAAA) {
4367b5038d7SDag-Erling Smørgrav 		return NULL;
4377b5038d7SDag-Erling Smørgrav 	}
4387b5038d7SDag-Erling Smørgrav 
4397b5038d7SDag-Erling Smørgrav 	in_addr = NULL;
4407b5038d7SDag-Erling Smørgrav 	ret_dname = NULL;
4417b5038d7SDag-Erling Smørgrav 
4427b5038d7SDag-Erling Smørgrav 	switch(ldns_rdf_get_type(rd)) {
4437b5038d7SDag-Erling Smørgrav 		case LDNS_RDF_TYPE_A:
4447b5038d7SDag-Erling Smørgrav 			/* the length of the buffer is 4 */
4457b5038d7SDag-Erling Smørgrav 			buf_4[3] = ldns_rdf_data(rd)[0];
4467b5038d7SDag-Erling Smørgrav 			buf_4[2] = ldns_rdf_data(rd)[1];
4477b5038d7SDag-Erling Smørgrav 			buf_4[1] = ldns_rdf_data(rd)[2];
4487b5038d7SDag-Erling Smørgrav 			buf_4[0] = ldns_rdf_data(rd)[3];
4497b5038d7SDag-Erling Smørgrav 			in_addr = ldns_dname_new_frm_str("in-addr.arpa.");
4507b5038d7SDag-Erling Smørgrav 			if (!in_addr) {
4517b5038d7SDag-Erling Smørgrav 				return NULL;
4527b5038d7SDag-Erling Smørgrav 			}
4537b5038d7SDag-Erling Smørgrav 			/* make a new rdf and convert that back  */
4547b5038d7SDag-Erling Smørgrav 			rev = ldns_rdf_new_frm_data( LDNS_RDF_TYPE_A,
4557b5038d7SDag-Erling Smørgrav 				LDNS_IP4ADDRLEN, (void*)&buf_4);
4567b5038d7SDag-Erling Smørgrav 			if (!rev) {
4577b5038d7SDag-Erling Smørgrav 				LDNS_FREE(in_addr);
4587b5038d7SDag-Erling Smørgrav 				return NULL;
4597b5038d7SDag-Erling Smørgrav 			}
4607b5038d7SDag-Erling Smørgrav 
4617b5038d7SDag-Erling Smørgrav 			/* convert rev to a string */
4627b5038d7SDag-Erling Smørgrav 			char_dname = ldns_rdf2str(rev);
4637b5038d7SDag-Erling Smørgrav 			if (!char_dname) {
4647b5038d7SDag-Erling Smørgrav 				LDNS_FREE(in_addr);
4657b5038d7SDag-Erling Smørgrav 				ldns_rdf_deep_free(rev);
4667b5038d7SDag-Erling Smørgrav 				return NULL;
4677b5038d7SDag-Erling Smørgrav 			}
4687b5038d7SDag-Erling Smørgrav 			/* transform back to rdf with type dname */
4697b5038d7SDag-Erling Smørgrav 			ret_dname = ldns_dname_new_frm_str(char_dname);
4707b5038d7SDag-Erling Smørgrav 			if (!ret_dname) {
4717b5038d7SDag-Erling Smørgrav 				LDNS_FREE(in_addr);
4727b5038d7SDag-Erling Smørgrav 				ldns_rdf_deep_free(rev);
4737b5038d7SDag-Erling Smørgrav 				LDNS_FREE(char_dname);
4747b5038d7SDag-Erling Smørgrav 				return NULL;
4757b5038d7SDag-Erling Smørgrav 			}
4767b5038d7SDag-Erling Smørgrav 			/* not needed anymore */
4777b5038d7SDag-Erling Smørgrav 			ldns_rdf_deep_free(rev);
4787b5038d7SDag-Erling Smørgrav 			LDNS_FREE(char_dname);
4797b5038d7SDag-Erling Smørgrav 			break;
4807b5038d7SDag-Erling Smørgrav 		case LDNS_RDF_TYPE_AAAA:
4817b5038d7SDag-Erling Smørgrav 			/* some foo magic to reverse the nibbles ... */
4827b5038d7SDag-Erling Smørgrav 
4837b5038d7SDag-Erling Smørgrav 			for (nbit = 127; nbit >= 0; nbit = nbit - 4) {
484986ba33cSDag-Erling Smørgrav 				/* calculate octet (8 bit) */
4857b5038d7SDag-Erling Smørgrav 				octet = ( ((unsigned int) nbit) & 0x78) >> 3;
4867b5038d7SDag-Erling Smørgrav 				/* calculate nibble */
4877b5038d7SDag-Erling Smørgrav 				nnibble = ( ((unsigned int) nbit) & 0x04) >> 2;
4887b5038d7SDag-Erling Smørgrav 				/* extract nibble */
4897b5038d7SDag-Erling Smørgrav 				nibble = (ldns_rdf_data(rd)[octet] & ( 0xf << (4 * (1 -
4907b5038d7SDag-Erling Smørgrav 						 nnibble)) ) ) >> ( 4 * (1 -
4917b5038d7SDag-Erling Smørgrav 						nnibble));
4927b5038d7SDag-Erling Smørgrav 
4937b5038d7SDag-Erling Smørgrav 				buf_6[(LDNS_IP6ADDRLEN * 2 - 1) -
4947b5038d7SDag-Erling Smørgrav 					(octet * 2 + nnibble)] =
4957b5038d7SDag-Erling Smørgrav 						(uint8_t)ldns_int_to_hexdigit((int)nibble);
4967b5038d7SDag-Erling Smørgrav 			}
4977b5038d7SDag-Erling Smørgrav 
4987b5038d7SDag-Erling Smørgrav 			char_dname = LDNS_XMALLOC(char, (LDNS_IP6ADDRLEN * 4));
4997b5038d7SDag-Erling Smørgrav 			if (!char_dname) {
5007b5038d7SDag-Erling Smørgrav 				return NULL;
5017b5038d7SDag-Erling Smørgrav 			}
5027b5038d7SDag-Erling Smørgrav 			char_dname[LDNS_IP6ADDRLEN * 4 - 1] = '\0'; /* closure */
5037b5038d7SDag-Erling Smørgrav 
5047b5038d7SDag-Erling Smørgrav 			/* walk the string and add . 's */
5057b5038d7SDag-Erling Smørgrav 			for (i = 0, j = 0; i < LDNS_IP6ADDRLEN * 2; i++, j = j + 2) {
5067b5038d7SDag-Erling Smørgrav 				char_dname[j] = (char)buf_6[i];
5077b5038d7SDag-Erling Smørgrav 				if (i != LDNS_IP6ADDRLEN * 2 - 1) {
5087b5038d7SDag-Erling Smørgrav 					char_dname[j + 1] = '.';
5097b5038d7SDag-Erling Smørgrav 				}
5107b5038d7SDag-Erling Smørgrav 			}
5117b5038d7SDag-Erling Smørgrav 			in_addr = ldns_dname_new_frm_str("ip6.arpa.");
5127b5038d7SDag-Erling Smørgrav 			if (!in_addr) {
5137b5038d7SDag-Erling Smørgrav 				LDNS_FREE(char_dname);
5147b5038d7SDag-Erling Smørgrav 				return NULL;
5157b5038d7SDag-Erling Smørgrav 			}
5167b5038d7SDag-Erling Smørgrav 
5177b5038d7SDag-Erling Smørgrav 			/* convert rev to a string */
5187b5038d7SDag-Erling Smørgrav 			ret_dname = ldns_dname_new_frm_str(char_dname);
5197b5038d7SDag-Erling Smørgrav 			LDNS_FREE(char_dname);
5207b5038d7SDag-Erling Smørgrav 			if (!ret_dname) {
5217b5038d7SDag-Erling Smørgrav 				ldns_rdf_deep_free(in_addr);
5227b5038d7SDag-Erling Smørgrav 				return NULL;
5237b5038d7SDag-Erling Smørgrav 			}
5247b5038d7SDag-Erling Smørgrav 			break;
5257b5038d7SDag-Erling Smørgrav 		default:
5267b5038d7SDag-Erling Smørgrav 			break;
5277b5038d7SDag-Erling Smørgrav 	}
5287b5038d7SDag-Erling Smørgrav 	/* add the suffix */
5297b5038d7SDag-Erling Smørgrav 	rev = ldns_dname_cat_clone(ret_dname, in_addr);
5307b5038d7SDag-Erling Smørgrav 
5317b5038d7SDag-Erling Smørgrav 	ldns_rdf_deep_free(ret_dname);
5327b5038d7SDag-Erling Smørgrav 	ldns_rdf_deep_free(in_addr);
5337b5038d7SDag-Erling Smørgrav 	return rev;
5347b5038d7SDag-Erling Smørgrav }
5357b5038d7SDag-Erling Smørgrav 
5367b5038d7SDag-Erling Smørgrav 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)53717d15b25SDag-Erling Smørgrav ldns_rdf_hip_get_alg_hit_pk(ldns_rdf *rdf, uint8_t* alg,
53817d15b25SDag-Erling Smørgrav                             uint8_t *hit_size, uint8_t** hit,
53917d15b25SDag-Erling Smørgrav                             uint16_t *pk_size, uint8_t** pk)
54017d15b25SDag-Erling Smørgrav {
54117d15b25SDag-Erling Smørgrav 	uint8_t *data;
54217d15b25SDag-Erling Smørgrav 	size_t rdf_size;
54317d15b25SDag-Erling Smørgrav 
54417d15b25SDag-Erling Smørgrav 	if (! rdf || ! alg || ! hit || ! hit_size || ! pk || ! pk_size) {
54517d15b25SDag-Erling Smørgrav 		return LDNS_STATUS_INVALID_POINTER;
54617d15b25SDag-Erling Smørgrav 	} else if (ldns_rdf_get_type(rdf) != LDNS_RDF_TYPE_HIP) {
54717d15b25SDag-Erling Smørgrav 		return LDNS_STATUS_INVALID_RDF_TYPE;
54817d15b25SDag-Erling Smørgrav 	} else if ((rdf_size = ldns_rdf_size(rdf)) < 6) {
54917d15b25SDag-Erling Smørgrav 		return LDNS_STATUS_WIRE_RDATA_ERR;
55017d15b25SDag-Erling Smørgrav 	}
55117d15b25SDag-Erling Smørgrav 	data = ldns_rdf_data(rdf);
55217d15b25SDag-Erling Smørgrav 	*hit_size = data[0];
55317d15b25SDag-Erling Smørgrav 	*alg      = data[1];
55417d15b25SDag-Erling Smørgrav 	*pk_size  = ldns_read_uint16(data + 2);
55517d15b25SDag-Erling Smørgrav 	*hit      = data + 4;
55617d15b25SDag-Erling Smørgrav 	*pk       = data + 4 + *hit_size;
55717d15b25SDag-Erling Smørgrav 	if (*hit_size == 0 || *pk_size == 0 ||
55817d15b25SDag-Erling Smørgrav 			rdf_size < (size_t) *hit_size + *pk_size + 4) {
55917d15b25SDag-Erling Smørgrav 		return LDNS_STATUS_WIRE_RDATA_ERR;
56017d15b25SDag-Erling Smørgrav 	}
56117d15b25SDag-Erling Smørgrav 	return LDNS_STATUS_OK;
56217d15b25SDag-Erling Smørgrav }
56317d15b25SDag-Erling Smørgrav 
56417d15b25SDag-Erling Smørgrav 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)56517d15b25SDag-Erling Smørgrav ldns_rdf_hip_new_frm_alg_hit_pk(ldns_rdf** rdf, uint8_t alg,
56617d15b25SDag-Erling Smørgrav                                 uint8_t hit_size, uint8_t *hit,
56717d15b25SDag-Erling Smørgrav 				uint16_t pk_size, uint8_t *pk)
56817d15b25SDag-Erling Smørgrav {
56917d15b25SDag-Erling Smørgrav 	uint8_t *data;
57017d15b25SDag-Erling Smørgrav 
57117d15b25SDag-Erling Smørgrav 	if (! rdf) {
57217d15b25SDag-Erling Smørgrav 		return LDNS_STATUS_INVALID_POINTER;
57317d15b25SDag-Erling Smørgrav 	}
57417d15b25SDag-Erling Smørgrav 	if (4 + hit_size + pk_size > LDNS_MAX_RDFLEN) {
57517d15b25SDag-Erling Smørgrav 		return LDNS_STATUS_RDATA_OVERFLOW;
57617d15b25SDag-Erling Smørgrav 	}
57717d15b25SDag-Erling Smørgrav 	data = LDNS_XMALLOC(uint8_t, 4 + hit_size + pk_size);
57817d15b25SDag-Erling Smørgrav 	if (data == NULL) {
57917d15b25SDag-Erling Smørgrav 		return LDNS_STATUS_MEM_ERR;
58017d15b25SDag-Erling Smørgrav 	}
58117d15b25SDag-Erling Smørgrav 	data[0] = hit_size;
58217d15b25SDag-Erling Smørgrav 	data[1] = alg;
58317d15b25SDag-Erling Smørgrav 	ldns_write_uint16(data + 2, pk_size);
58417d15b25SDag-Erling Smørgrav 	memcpy(data + 4, hit, hit_size);
58517d15b25SDag-Erling Smørgrav 	memcpy(data + 4 + hit_size, pk, pk_size);
58617d15b25SDag-Erling Smørgrav 	*rdf = ldns_rdf_new(LDNS_RDF_TYPE_HIP, 4 + hit_size + pk_size, data);
58717d15b25SDag-Erling Smørgrav 	if (! *rdf) {
58817d15b25SDag-Erling Smørgrav 		LDNS_FREE(data);
58917d15b25SDag-Erling Smørgrav 		return LDNS_STATUS_MEM_ERR;
59017d15b25SDag-Erling Smørgrav 	}
59117d15b25SDag-Erling Smørgrav 	return LDNS_STATUS_OK;
59217d15b25SDag-Erling Smørgrav }
59317d15b25SDag-Erling Smørgrav 
59417d15b25SDag-Erling Smørgrav ldns_status
ldns_octet(char * word,size_t * length)5957b5038d7SDag-Erling Smørgrav ldns_octet(char *word, size_t *length)
5967b5038d7SDag-Erling Smørgrav {
5977b5038d7SDag-Erling Smørgrav     char *s;
5987b5038d7SDag-Erling Smørgrav     char *p;
5997b5038d7SDag-Erling Smørgrav     *length = 0;
6007b5038d7SDag-Erling Smørgrav 
6017b5038d7SDag-Erling Smørgrav     for (s = p = word; *s != '\0'; s++,p++) {
6027b5038d7SDag-Erling Smørgrav         switch (*s) {
6037b5038d7SDag-Erling Smørgrav             case '.':
6047b5038d7SDag-Erling Smørgrav                 if (s[1] == '.') {
6057b5038d7SDag-Erling Smørgrav 		    return LDNS_STATUS_EMPTY_LABEL;
6067b5038d7SDag-Erling Smørgrav                 }
6077b5038d7SDag-Erling Smørgrav                 *p = *s;
6087b5038d7SDag-Erling Smørgrav                 (*length)++;
6097b5038d7SDag-Erling Smørgrav                 break;
6107b5038d7SDag-Erling Smørgrav             case '\\':
6117b5038d7SDag-Erling Smørgrav                 if ('0' <= s[1] && s[1] <= '9' &&
6127b5038d7SDag-Erling Smørgrav                     '0' <= s[2] && s[2] <= '9' &&
6137b5038d7SDag-Erling Smørgrav                     '0' <= s[3] && s[3] <= '9') {
6147b5038d7SDag-Erling Smørgrav                     /* \DDD seen */
6157b5038d7SDag-Erling Smørgrav                     int val = ((s[1] - '0') * 100 +
6167b5038d7SDag-Erling Smørgrav                            (s[2] - '0') * 10 + (s[3] - '0'));
6177b5038d7SDag-Erling Smørgrav 
6187b5038d7SDag-Erling Smørgrav                     if (0 <= val && val <= 255) {
6197b5038d7SDag-Erling Smørgrav                         /* this also handles \0 */
6207b5038d7SDag-Erling Smørgrav                         s += 3;
6217b5038d7SDag-Erling Smørgrav                         *p = val;
6227b5038d7SDag-Erling Smørgrav                         (*length)++;
6237b5038d7SDag-Erling Smørgrav                     } else {
6247b5038d7SDag-Erling Smørgrav                         return LDNS_STATUS_DDD_OVERFLOW;
6257b5038d7SDag-Erling Smørgrav                     }
6267b5038d7SDag-Erling Smørgrav                 } else {
627*5afab0e5SDag-Erling Smørgrav                     /* an escaped character, like \<space> ?
6287b5038d7SDag-Erling Smørgrav                     * remove the '\' keep the rest */
6297b5038d7SDag-Erling Smørgrav                     *p = *++s;
6307b5038d7SDag-Erling Smørgrav                     (*length)++;
6317b5038d7SDag-Erling Smørgrav                 }
6327b5038d7SDag-Erling Smørgrav                 break;
6337b5038d7SDag-Erling Smørgrav             case '\"':
6347b5038d7SDag-Erling Smørgrav                 /* non quoted " Is either first or the last character in
6357b5038d7SDag-Erling Smørgrav                  * the string */
6367b5038d7SDag-Erling Smørgrav 
6377b5038d7SDag-Erling Smørgrav                 *p = *++s; /* skip it */
6387b5038d7SDag-Erling Smørgrav                 (*length)++;
6397b5038d7SDag-Erling Smørgrav 		/* I'm not sure if this is needed in libdns... MG */
6407b5038d7SDag-Erling Smørgrav                 if ( *s == '\0' ) {
6417b5038d7SDag-Erling Smørgrav                     /* ok, it was the last one */
6427b5038d7SDag-Erling Smørgrav                     *p  = '\0';
6437b5038d7SDag-Erling Smørgrav 		    return LDNS_STATUS_OK;
6447b5038d7SDag-Erling Smørgrav                 }
6457b5038d7SDag-Erling Smørgrav                 break;
6467b5038d7SDag-Erling Smørgrav             default:
6477b5038d7SDag-Erling Smørgrav                 *p = *s;
6487b5038d7SDag-Erling Smørgrav                 (*length)++;
6497b5038d7SDag-Erling Smørgrav                 break;
6507b5038d7SDag-Erling Smørgrav         }
6517b5038d7SDag-Erling Smørgrav     }
6527b5038d7SDag-Erling Smørgrav     *p = '\0';
6537b5038d7SDag-Erling Smørgrav     return LDNS_STATUS_OK;
6547b5038d7SDag-Erling Smørgrav }
6557b5038d7SDag-Erling Smørgrav 
6567b5038d7SDag-Erling Smørgrav int
ldns_rdf_compare(const ldns_rdf * rd1,const ldns_rdf * rd2)6577b5038d7SDag-Erling Smørgrav ldns_rdf_compare(const ldns_rdf *rd1, const ldns_rdf *rd2)
6587b5038d7SDag-Erling Smørgrav {
6597b5038d7SDag-Erling Smørgrav 	uint16_t i1, i2, i;
6607b5038d7SDag-Erling Smørgrav 	uint8_t *d1, *d2;
6617b5038d7SDag-Erling Smørgrav 
6627b5038d7SDag-Erling Smørgrav 	/* only when both are not NULL we can say anything about them */
6637b5038d7SDag-Erling Smørgrav 	if (!rd1 && !rd2) {
6647b5038d7SDag-Erling Smørgrav 		return 0;
6657b5038d7SDag-Erling Smørgrav 	}
6667b5038d7SDag-Erling Smørgrav 	if (!rd1 || !rd2) {
6677b5038d7SDag-Erling Smørgrav 		return -1;
6687b5038d7SDag-Erling Smørgrav 	}
6697b5038d7SDag-Erling Smørgrav 	i1 = ldns_rdf_size(rd1);
6707b5038d7SDag-Erling Smørgrav 	i2 = ldns_rdf_size(rd2);
6717b5038d7SDag-Erling Smørgrav 
6727b5038d7SDag-Erling Smørgrav 	if (i1 < i2) {
6737b5038d7SDag-Erling Smørgrav 		return -1;
6747b5038d7SDag-Erling Smørgrav 	} else if (i1 > i2) {
6757b5038d7SDag-Erling Smørgrav 		return +1;
6767b5038d7SDag-Erling Smørgrav 	} else {
6777b5038d7SDag-Erling Smørgrav 		d1 = (uint8_t*)ldns_rdf_data(rd1);
6787b5038d7SDag-Erling Smørgrav 		d2 = (uint8_t*)ldns_rdf_data(rd2);
6797b5038d7SDag-Erling Smørgrav 		for(i = 0; i < i1; i++) {
6807b5038d7SDag-Erling Smørgrav 			if (d1[i] < d2[i]) {
6817b5038d7SDag-Erling Smørgrav 				return -1;
6827b5038d7SDag-Erling Smørgrav 			} else if (d1[i] > d2[i]) {
6837b5038d7SDag-Erling Smørgrav 				return +1;
6847b5038d7SDag-Erling Smørgrav 			}
6857b5038d7SDag-Erling Smørgrav 		}
6867b5038d7SDag-Erling Smørgrav 	}
6877b5038d7SDag-Erling Smørgrav 	return 0;
6887b5038d7SDag-Erling Smørgrav }
6897b5038d7SDag-Erling Smørgrav 
6907b5038d7SDag-Erling Smørgrav uint32_t
ldns_str2period(const char * nptr,const char ** endptr)6917b5038d7SDag-Erling Smørgrav ldns_str2period(const char *nptr, const char **endptr)
6927b5038d7SDag-Erling Smørgrav {
6937b5038d7SDag-Erling Smørgrav 	int sign = 0;
6947b5038d7SDag-Erling Smørgrav 	uint32_t i = 0;
6957b5038d7SDag-Erling Smørgrav 	uint32_t seconds = 0;
6967b5038d7SDag-Erling Smørgrav 
6977b5038d7SDag-Erling Smørgrav 	for(*endptr = nptr; **endptr; (*endptr)++) {
6987b5038d7SDag-Erling Smørgrav 		switch (**endptr) {
6997b5038d7SDag-Erling Smørgrav 			case ' ':
7007b5038d7SDag-Erling Smørgrav 			case '\t':
7017b5038d7SDag-Erling Smørgrav 				break;
7027b5038d7SDag-Erling Smørgrav 			case '-':
7037b5038d7SDag-Erling Smørgrav 				if(sign == 0) {
7047b5038d7SDag-Erling Smørgrav 					sign = -1;
7057b5038d7SDag-Erling Smørgrav 				} else {
7067b5038d7SDag-Erling Smørgrav 					return seconds;
7077b5038d7SDag-Erling Smørgrav 				}
7087b5038d7SDag-Erling Smørgrav 				break;
7097b5038d7SDag-Erling Smørgrav 			case '+':
7107b5038d7SDag-Erling Smørgrav 				if(sign == 0) {
7117b5038d7SDag-Erling Smørgrav 					sign = 1;
7127b5038d7SDag-Erling Smørgrav 				} else {
7137b5038d7SDag-Erling Smørgrav 					return seconds;
7147b5038d7SDag-Erling Smørgrav 				}
7157b5038d7SDag-Erling Smørgrav 				break;
7167b5038d7SDag-Erling Smørgrav 			case 's':
7177b5038d7SDag-Erling Smørgrav 			case 'S':
7187b5038d7SDag-Erling Smørgrav 				seconds += i;
7197b5038d7SDag-Erling Smørgrav 				i = 0;
7207b5038d7SDag-Erling Smørgrav 				break;
7217b5038d7SDag-Erling Smørgrav 			case 'm':
7227b5038d7SDag-Erling Smørgrav 			case 'M':
7237b5038d7SDag-Erling Smørgrav 				seconds += i * 60;
7247b5038d7SDag-Erling Smørgrav 				i = 0;
7257b5038d7SDag-Erling Smørgrav 				break;
7267b5038d7SDag-Erling Smørgrav 			case 'h':
7277b5038d7SDag-Erling Smørgrav 			case 'H':
7287b5038d7SDag-Erling Smørgrav 				seconds += i * 60 * 60;
7297b5038d7SDag-Erling Smørgrav 				i = 0;
7307b5038d7SDag-Erling Smørgrav 				break;
7317b5038d7SDag-Erling Smørgrav 			case 'd':
7327b5038d7SDag-Erling Smørgrav 			case 'D':
7337b5038d7SDag-Erling Smørgrav 				seconds += i * 60 * 60 * 24;
7347b5038d7SDag-Erling Smørgrav 				i = 0;
7357b5038d7SDag-Erling Smørgrav 				break;
7367b5038d7SDag-Erling Smørgrav 			case 'w':
7377b5038d7SDag-Erling Smørgrav 			case 'W':
7387b5038d7SDag-Erling Smørgrav 				seconds += i * 60 * 60 * 24 * 7;
7397b5038d7SDag-Erling Smørgrav 				i = 0;
7407b5038d7SDag-Erling Smørgrav 				break;
7417b5038d7SDag-Erling Smørgrav 			case '0':
7427b5038d7SDag-Erling Smørgrav 			case '1':
7437b5038d7SDag-Erling Smørgrav 			case '2':
7447b5038d7SDag-Erling Smørgrav 			case '3':
7457b5038d7SDag-Erling Smørgrav 			case '4':
7467b5038d7SDag-Erling Smørgrav 			case '5':
7477b5038d7SDag-Erling Smørgrav 			case '6':
7487b5038d7SDag-Erling Smørgrav 			case '7':
7497b5038d7SDag-Erling Smørgrav 			case '8':
7507b5038d7SDag-Erling Smørgrav 			case '9':
7517b5038d7SDag-Erling Smørgrav 				i *= 10;
7527b5038d7SDag-Erling Smørgrav 				i += (**endptr - '0');
7537b5038d7SDag-Erling Smørgrav 				break;
7547b5038d7SDag-Erling Smørgrav 			default:
7557b5038d7SDag-Erling Smørgrav 				seconds += i;
7567b5038d7SDag-Erling Smørgrav 				/* disregard signedness */
7577b5038d7SDag-Erling Smørgrav 				return seconds;
7587b5038d7SDag-Erling Smørgrav 		}
7597b5038d7SDag-Erling Smørgrav 	}
7607b5038d7SDag-Erling Smørgrav 	seconds += i;
7617b5038d7SDag-Erling Smørgrav 	/* disregard signedness */
7627b5038d7SDag-Erling Smørgrav 	return seconds;
7637b5038d7SDag-Erling Smørgrav }
764