xref: /freebsd/contrib/ldns/rdata.c (revision 17d15b251108ff09e632ed4812f7c66999a6b69b)
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
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
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 *
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
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
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
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
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
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
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
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 
116*17d15b25SDag-Erling Smørgrav 	/* only allow 32 bit rdfs */
117*17d15b25SDag-Erling Smørgrav 	if (ldns_rdf_size(rd) != LDNS_RDF_SIZE_DOUBLEWORD ||
118*17d15b25SDag-Erling Smørgrav 			ldns_rdf_get_type(rd) != LDNS_RDF_TYPE_TIME) {
1197b5038d7SDag-Erling Smørgrav 		return 0;
1207b5038d7SDag-Erling Smørgrav 	}
121*17d15b25SDag-Erling Smørgrav 	memcpy(&data, ldns_rdf_data(rd), sizeof(data));
122*17d15b25SDag-Erling Smørgrav 	return (time_t)ntohl(data);
1237b5038d7SDag-Erling Smørgrav }
1247b5038d7SDag-Erling Smørgrav 
1257b5038d7SDag-Erling Smørgrav ldns_rdf *
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 *
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 *
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 *
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 *
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 *
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 *
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
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
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 *
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;
312*17d15b25SDag-Erling Smørgrav 	case LDNS_RDF_TYPE_HIP:
313*17d15b25SDag-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;
339*17d15b25SDag-Erling Smørgrav 	case LDNS_RDF_TYPE_ILNP64:
340*17d15b25SDag-Erling Smørgrav 		status = ldns_str2rdf_ilnp64(&rdf, str);
341*17d15b25SDag-Erling Smørgrav 		break;
342*17d15b25SDag-Erling Smørgrav 	case LDNS_RDF_TYPE_EUI48:
343*17d15b25SDag-Erling Smørgrav 		status = ldns_str2rdf_eui48(&rdf, str);
344*17d15b25SDag-Erling Smørgrav 		break;
345*17d15b25SDag-Erling Smørgrav 	case LDNS_RDF_TYPE_EUI64:
346*17d15b25SDag-Erling Smørgrav 		status = ldns_str2rdf_eui64(&rdf, str);
347*17d15b25SDag-Erling Smørgrav 		break;
348*17d15b25SDag-Erling Smørgrav 	case LDNS_RDF_TYPE_TAG:
349*17d15b25SDag-Erling Smørgrav 		status = ldns_str2rdf_tag(&rdf, str);
350*17d15b25SDag-Erling Smørgrav 		break;
351*17d15b25SDag-Erling Smørgrav 	case LDNS_RDF_TYPE_LONG_STR:
352*17d15b25SDag-Erling Smørgrav 		status = ldns_str2rdf_long_str(&rdf, str);
353*17d15b25SDag-Erling Smørgrav 		break;
3547b5038d7SDag-Erling Smørgrav 	case LDNS_RDF_TYPE_NONE:
3557b5038d7SDag-Erling Smørgrav 	default:
3567b5038d7SDag-Erling Smørgrav 		/* default default ??? */
3577b5038d7SDag-Erling Smørgrav 		status = LDNS_STATUS_ERR;
3587b5038d7SDag-Erling Smørgrav 		break;
3597b5038d7SDag-Erling Smørgrav 	}
3607b5038d7SDag-Erling Smørgrav 	if (LDNS_STATUS_OK == status) {
3617b5038d7SDag-Erling Smørgrav 		ldns_rdf_set_type(rdf, type);
3627b5038d7SDag-Erling Smørgrav 		return rdf;
3637b5038d7SDag-Erling Smørgrav 	}
3647b5038d7SDag-Erling Smørgrav 	if (rdf) {
3657b5038d7SDag-Erling Smørgrav 		LDNS_FREE(rdf);
3667b5038d7SDag-Erling Smørgrav 	}
3677b5038d7SDag-Erling Smørgrav 	return NULL;
3687b5038d7SDag-Erling Smørgrav }
3697b5038d7SDag-Erling Smørgrav 
3707b5038d7SDag-Erling Smørgrav ldns_status
3717b5038d7SDag-Erling Smørgrav ldns_rdf_new_frm_fp(ldns_rdf **rdf, ldns_rdf_type type, FILE *fp)
3727b5038d7SDag-Erling Smørgrav {
3737b5038d7SDag-Erling Smørgrav 	return ldns_rdf_new_frm_fp_l(rdf, type, fp, NULL);
3747b5038d7SDag-Erling Smørgrav }
3757b5038d7SDag-Erling Smørgrav 
3767b5038d7SDag-Erling Smørgrav ldns_status
3777b5038d7SDag-Erling Smørgrav ldns_rdf_new_frm_fp_l(ldns_rdf **rdf, ldns_rdf_type type, FILE *fp, int *line_nr)
3787b5038d7SDag-Erling Smørgrav {
3797b5038d7SDag-Erling Smørgrav 	char *line;
3807b5038d7SDag-Erling Smørgrav 	ldns_rdf *r;
3817b5038d7SDag-Erling Smørgrav 	ssize_t t;
3827b5038d7SDag-Erling Smørgrav 
3837b5038d7SDag-Erling Smørgrav 	line = LDNS_XMALLOC(char, LDNS_MAX_LINELEN + 1);
3847b5038d7SDag-Erling Smørgrav 	if (!line) {
3857b5038d7SDag-Erling Smørgrav 		return LDNS_STATUS_MEM_ERR;
3867b5038d7SDag-Erling Smørgrav 	}
3877b5038d7SDag-Erling Smørgrav 
3887b5038d7SDag-Erling Smørgrav 	/* read an entire line in from the file */
3897b5038d7SDag-Erling Smørgrav 	if ((t = ldns_fget_token_l(fp, line, LDNS_PARSE_SKIP_SPACE, 0, line_nr)) == -1 || t == 0) {
3907b5038d7SDag-Erling Smørgrav 		LDNS_FREE(line);
3917b5038d7SDag-Erling Smørgrav 		return LDNS_STATUS_SYNTAX_RDATA_ERR;
3927b5038d7SDag-Erling Smørgrav 	}
3937b5038d7SDag-Erling Smørgrav 	r =  ldns_rdf_new_frm_str(type, (const char*) line);
3947b5038d7SDag-Erling Smørgrav 	LDNS_FREE(line);
3957b5038d7SDag-Erling Smørgrav 	if (rdf) {
3967b5038d7SDag-Erling Smørgrav 		*rdf = r;
3977b5038d7SDag-Erling Smørgrav 		return LDNS_STATUS_OK;
3987b5038d7SDag-Erling Smørgrav 	} else {
3997b5038d7SDag-Erling Smørgrav 		return LDNS_STATUS_NULL;
4007b5038d7SDag-Erling Smørgrav 	}
4017b5038d7SDag-Erling Smørgrav }
4027b5038d7SDag-Erling Smørgrav 
4037b5038d7SDag-Erling Smørgrav ldns_rdf *
4047b5038d7SDag-Erling Smørgrav ldns_rdf_address_reverse(ldns_rdf *rd)
4057b5038d7SDag-Erling Smørgrav {
4067b5038d7SDag-Erling Smørgrav 	uint8_t buf_4[LDNS_IP4ADDRLEN];
4077b5038d7SDag-Erling Smørgrav 	uint8_t buf_6[LDNS_IP6ADDRLEN * 2];
4087b5038d7SDag-Erling Smørgrav 	ldns_rdf *rev;
4097b5038d7SDag-Erling Smørgrav 	ldns_rdf *in_addr;
4107b5038d7SDag-Erling Smørgrav 	ldns_rdf *ret_dname;
4117b5038d7SDag-Erling Smørgrav 	uint8_t octet;
4127b5038d7SDag-Erling Smørgrav 	uint8_t nnibble;
4137b5038d7SDag-Erling Smørgrav 	uint8_t nibble;
4147b5038d7SDag-Erling Smørgrav 	uint8_t i, j;
4157b5038d7SDag-Erling Smørgrav 
4167b5038d7SDag-Erling Smørgrav 	char *char_dname;
4177b5038d7SDag-Erling Smørgrav 	int nbit;
4187b5038d7SDag-Erling Smørgrav 
4197b5038d7SDag-Erling Smørgrav 	if (ldns_rdf_get_type(rd) != LDNS_RDF_TYPE_A &&
4207b5038d7SDag-Erling Smørgrav 			ldns_rdf_get_type(rd) != LDNS_RDF_TYPE_AAAA) {
4217b5038d7SDag-Erling Smørgrav 		return NULL;
4227b5038d7SDag-Erling Smørgrav 	}
4237b5038d7SDag-Erling Smørgrav 
4247b5038d7SDag-Erling Smørgrav 	in_addr = NULL;
4257b5038d7SDag-Erling Smørgrav 	ret_dname = NULL;
4267b5038d7SDag-Erling Smørgrav 
4277b5038d7SDag-Erling Smørgrav 	switch(ldns_rdf_get_type(rd)) {
4287b5038d7SDag-Erling Smørgrav 		case LDNS_RDF_TYPE_A:
4297b5038d7SDag-Erling Smørgrav 			/* the length of the buffer is 4 */
4307b5038d7SDag-Erling Smørgrav 			buf_4[3] = ldns_rdf_data(rd)[0];
4317b5038d7SDag-Erling Smørgrav 			buf_4[2] = ldns_rdf_data(rd)[1];
4327b5038d7SDag-Erling Smørgrav 			buf_4[1] = ldns_rdf_data(rd)[2];
4337b5038d7SDag-Erling Smørgrav 			buf_4[0] = ldns_rdf_data(rd)[3];
4347b5038d7SDag-Erling Smørgrav 			in_addr = ldns_dname_new_frm_str("in-addr.arpa.");
4357b5038d7SDag-Erling Smørgrav 			if (!in_addr) {
4367b5038d7SDag-Erling Smørgrav 				return NULL;
4377b5038d7SDag-Erling Smørgrav 			}
4387b5038d7SDag-Erling Smørgrav 			/* make a new rdf and convert that back  */
4397b5038d7SDag-Erling Smørgrav 			rev = ldns_rdf_new_frm_data( LDNS_RDF_TYPE_A,
4407b5038d7SDag-Erling Smørgrav 				LDNS_IP4ADDRLEN, (void*)&buf_4);
4417b5038d7SDag-Erling Smørgrav 			if (!rev) {
4427b5038d7SDag-Erling Smørgrav 				LDNS_FREE(in_addr);
4437b5038d7SDag-Erling Smørgrav 				return NULL;
4447b5038d7SDag-Erling Smørgrav 			}
4457b5038d7SDag-Erling Smørgrav 
4467b5038d7SDag-Erling Smørgrav 			/* convert rev to a string */
4477b5038d7SDag-Erling Smørgrav 			char_dname = ldns_rdf2str(rev);
4487b5038d7SDag-Erling Smørgrav 			if (!char_dname) {
4497b5038d7SDag-Erling Smørgrav 				LDNS_FREE(in_addr);
4507b5038d7SDag-Erling Smørgrav 				ldns_rdf_deep_free(rev);
4517b5038d7SDag-Erling Smørgrav 				return NULL;
4527b5038d7SDag-Erling Smørgrav 			}
4537b5038d7SDag-Erling Smørgrav 			/* transform back to rdf with type dname */
4547b5038d7SDag-Erling Smørgrav 			ret_dname = ldns_dname_new_frm_str(char_dname);
4557b5038d7SDag-Erling Smørgrav 			if (!ret_dname) {
4567b5038d7SDag-Erling Smørgrav 				LDNS_FREE(in_addr);
4577b5038d7SDag-Erling Smørgrav 				ldns_rdf_deep_free(rev);
4587b5038d7SDag-Erling Smørgrav 				LDNS_FREE(char_dname);
4597b5038d7SDag-Erling Smørgrav 				return NULL;
4607b5038d7SDag-Erling Smørgrav 			}
4617b5038d7SDag-Erling Smørgrav 			/* not needed anymore */
4627b5038d7SDag-Erling Smørgrav 			ldns_rdf_deep_free(rev);
4637b5038d7SDag-Erling Smørgrav 			LDNS_FREE(char_dname);
4647b5038d7SDag-Erling Smørgrav 			break;
4657b5038d7SDag-Erling Smørgrav 		case LDNS_RDF_TYPE_AAAA:
4667b5038d7SDag-Erling Smørgrav 			/* some foo magic to reverse the nibbles ... */
4677b5038d7SDag-Erling Smørgrav 
4687b5038d7SDag-Erling Smørgrav 			for (nbit = 127; nbit >= 0; nbit = nbit - 4) {
4697b5038d7SDag-Erling Smørgrav 				/* calculate octett (8 bit) */
4707b5038d7SDag-Erling Smørgrav 				octet = ( ((unsigned int) nbit) & 0x78) >> 3;
4717b5038d7SDag-Erling Smørgrav 				/* calculate nibble */
4727b5038d7SDag-Erling Smørgrav 				nnibble = ( ((unsigned int) nbit) & 0x04) >> 2;
4737b5038d7SDag-Erling Smørgrav 				/* extract nibble */
4747b5038d7SDag-Erling Smørgrav 				nibble = (ldns_rdf_data(rd)[octet] & ( 0xf << (4 * (1 -
4757b5038d7SDag-Erling Smørgrav 						 nnibble)) ) ) >> ( 4 * (1 -
4767b5038d7SDag-Erling Smørgrav 						nnibble));
4777b5038d7SDag-Erling Smørgrav 
4787b5038d7SDag-Erling Smørgrav 				buf_6[(LDNS_IP6ADDRLEN * 2 - 1) -
4797b5038d7SDag-Erling Smørgrav 					(octet * 2 + nnibble)] =
4807b5038d7SDag-Erling Smørgrav 						(uint8_t)ldns_int_to_hexdigit((int)nibble);
4817b5038d7SDag-Erling Smørgrav 			}
4827b5038d7SDag-Erling Smørgrav 
4837b5038d7SDag-Erling Smørgrav 			char_dname = LDNS_XMALLOC(char, (LDNS_IP6ADDRLEN * 4));
4847b5038d7SDag-Erling Smørgrav 			if (!char_dname) {
4857b5038d7SDag-Erling Smørgrav 				return NULL;
4867b5038d7SDag-Erling Smørgrav 			}
4877b5038d7SDag-Erling Smørgrav 			char_dname[LDNS_IP6ADDRLEN * 4 - 1] = '\0'; /* closure */
4887b5038d7SDag-Erling Smørgrav 
4897b5038d7SDag-Erling Smørgrav 			/* walk the string and add . 's */
4907b5038d7SDag-Erling Smørgrav 			for (i = 0, j = 0; i < LDNS_IP6ADDRLEN * 2; i++, j = j + 2) {
4917b5038d7SDag-Erling Smørgrav 				char_dname[j] = (char)buf_6[i];
4927b5038d7SDag-Erling Smørgrav 				if (i != LDNS_IP6ADDRLEN * 2 - 1) {
4937b5038d7SDag-Erling Smørgrav 					char_dname[j + 1] = '.';
4947b5038d7SDag-Erling Smørgrav 				}
4957b5038d7SDag-Erling Smørgrav 			}
4967b5038d7SDag-Erling Smørgrav 			in_addr = ldns_dname_new_frm_str("ip6.arpa.");
4977b5038d7SDag-Erling Smørgrav 			if (!in_addr) {
4987b5038d7SDag-Erling Smørgrav 				LDNS_FREE(char_dname);
4997b5038d7SDag-Erling Smørgrav 				return NULL;
5007b5038d7SDag-Erling Smørgrav 			}
5017b5038d7SDag-Erling Smørgrav 
5027b5038d7SDag-Erling Smørgrav 			/* convert rev to a string */
5037b5038d7SDag-Erling Smørgrav 			ret_dname = ldns_dname_new_frm_str(char_dname);
5047b5038d7SDag-Erling Smørgrav 			LDNS_FREE(char_dname);
5057b5038d7SDag-Erling Smørgrav 			if (!ret_dname) {
5067b5038d7SDag-Erling Smørgrav 				ldns_rdf_deep_free(in_addr);
5077b5038d7SDag-Erling Smørgrav 				return NULL;
5087b5038d7SDag-Erling Smørgrav 			}
5097b5038d7SDag-Erling Smørgrav 			break;
5107b5038d7SDag-Erling Smørgrav 		default:
5117b5038d7SDag-Erling Smørgrav 			break;
5127b5038d7SDag-Erling Smørgrav 	}
5137b5038d7SDag-Erling Smørgrav 	/* add the suffix */
5147b5038d7SDag-Erling Smørgrav 	rev = ldns_dname_cat_clone(ret_dname, in_addr);
5157b5038d7SDag-Erling Smørgrav 
5167b5038d7SDag-Erling Smørgrav 	ldns_rdf_deep_free(ret_dname);
5177b5038d7SDag-Erling Smørgrav 	ldns_rdf_deep_free(in_addr);
5187b5038d7SDag-Erling Smørgrav 	return rev;
5197b5038d7SDag-Erling Smørgrav }
5207b5038d7SDag-Erling Smørgrav 
5217b5038d7SDag-Erling Smørgrav ldns_status
522*17d15b25SDag-Erling Smørgrav ldns_rdf_hip_get_alg_hit_pk(ldns_rdf *rdf, uint8_t* alg,
523*17d15b25SDag-Erling Smørgrav                             uint8_t *hit_size, uint8_t** hit,
524*17d15b25SDag-Erling Smørgrav                             uint16_t *pk_size, uint8_t** pk)
525*17d15b25SDag-Erling Smørgrav {
526*17d15b25SDag-Erling Smørgrav 	uint8_t *data;
527*17d15b25SDag-Erling Smørgrav 	size_t rdf_size;
528*17d15b25SDag-Erling Smørgrav 
529*17d15b25SDag-Erling Smørgrav 	if (! rdf || ! alg || ! hit || ! hit_size || ! pk || ! pk_size) {
530*17d15b25SDag-Erling Smørgrav 		return LDNS_STATUS_INVALID_POINTER;
531*17d15b25SDag-Erling Smørgrav 	} else if (ldns_rdf_get_type(rdf) != LDNS_RDF_TYPE_HIP) {
532*17d15b25SDag-Erling Smørgrav 		return LDNS_STATUS_INVALID_RDF_TYPE;
533*17d15b25SDag-Erling Smørgrav 	} else if ((rdf_size = ldns_rdf_size(rdf)) < 6) {
534*17d15b25SDag-Erling Smørgrav 		return LDNS_STATUS_WIRE_RDATA_ERR;
535*17d15b25SDag-Erling Smørgrav 	}
536*17d15b25SDag-Erling Smørgrav 	data = ldns_rdf_data(rdf);
537*17d15b25SDag-Erling Smørgrav 	*hit_size = data[0];
538*17d15b25SDag-Erling Smørgrav 	*alg      = data[1];
539*17d15b25SDag-Erling Smørgrav 	*pk_size  = ldns_read_uint16(data + 2);
540*17d15b25SDag-Erling Smørgrav 	*hit      = data + 4;
541*17d15b25SDag-Erling Smørgrav 	*pk       = data + 4 + *hit_size;
542*17d15b25SDag-Erling Smørgrav 	if (*hit_size == 0 || *pk_size == 0 ||
543*17d15b25SDag-Erling Smørgrav 			rdf_size < (size_t) *hit_size + *pk_size + 4) {
544*17d15b25SDag-Erling Smørgrav 		return LDNS_STATUS_WIRE_RDATA_ERR;
545*17d15b25SDag-Erling Smørgrav 	}
546*17d15b25SDag-Erling Smørgrav 	return LDNS_STATUS_OK;
547*17d15b25SDag-Erling Smørgrav }
548*17d15b25SDag-Erling Smørgrav 
549*17d15b25SDag-Erling Smørgrav ldns_status
550*17d15b25SDag-Erling Smørgrav ldns_rdf_hip_new_frm_alg_hit_pk(ldns_rdf** rdf, uint8_t alg,
551*17d15b25SDag-Erling Smørgrav                                 uint8_t hit_size, uint8_t *hit,
552*17d15b25SDag-Erling Smørgrav 				uint16_t pk_size, uint8_t *pk)
553*17d15b25SDag-Erling Smørgrav {
554*17d15b25SDag-Erling Smørgrav 	uint8_t *data;
555*17d15b25SDag-Erling Smørgrav 
556*17d15b25SDag-Erling Smørgrav 	if (! rdf) {
557*17d15b25SDag-Erling Smørgrav 		return LDNS_STATUS_INVALID_POINTER;
558*17d15b25SDag-Erling Smørgrav 	}
559*17d15b25SDag-Erling Smørgrav 	if (4 + hit_size + pk_size > LDNS_MAX_RDFLEN) {
560*17d15b25SDag-Erling Smørgrav 		return LDNS_STATUS_RDATA_OVERFLOW;
561*17d15b25SDag-Erling Smørgrav 	}
562*17d15b25SDag-Erling Smørgrav 	data = LDNS_XMALLOC(uint8_t, 4 + hit_size + pk_size);
563*17d15b25SDag-Erling Smørgrav 	if (data == NULL) {
564*17d15b25SDag-Erling Smørgrav 		return LDNS_STATUS_MEM_ERR;
565*17d15b25SDag-Erling Smørgrav 	}
566*17d15b25SDag-Erling Smørgrav 	data[0] = hit_size;
567*17d15b25SDag-Erling Smørgrav 	data[1] = alg;
568*17d15b25SDag-Erling Smørgrav 	ldns_write_uint16(data + 2, pk_size);
569*17d15b25SDag-Erling Smørgrav 	memcpy(data + 4, hit, hit_size);
570*17d15b25SDag-Erling Smørgrav 	memcpy(data + 4 + hit_size, pk, pk_size);
571*17d15b25SDag-Erling Smørgrav 	*rdf = ldns_rdf_new(LDNS_RDF_TYPE_HIP, 4 + hit_size + pk_size, data);
572*17d15b25SDag-Erling Smørgrav 	if (! *rdf) {
573*17d15b25SDag-Erling Smørgrav 		LDNS_FREE(data);
574*17d15b25SDag-Erling Smørgrav 		return LDNS_STATUS_MEM_ERR;
575*17d15b25SDag-Erling Smørgrav 	}
576*17d15b25SDag-Erling Smørgrav 	return LDNS_STATUS_OK;
577*17d15b25SDag-Erling Smørgrav }
578*17d15b25SDag-Erling Smørgrav 
579*17d15b25SDag-Erling Smørgrav ldns_status
5807b5038d7SDag-Erling Smørgrav ldns_octet(char *word, size_t *length)
5817b5038d7SDag-Erling Smørgrav {
5827b5038d7SDag-Erling Smørgrav     char *s;
5837b5038d7SDag-Erling Smørgrav     char *p;
5847b5038d7SDag-Erling Smørgrav     *length = 0;
5857b5038d7SDag-Erling Smørgrav 
5867b5038d7SDag-Erling Smørgrav     for (s = p = word; *s != '\0'; s++,p++) {
5877b5038d7SDag-Erling Smørgrav         switch (*s) {
5887b5038d7SDag-Erling Smørgrav             case '.':
5897b5038d7SDag-Erling Smørgrav                 if (s[1] == '.') {
5907b5038d7SDag-Erling Smørgrav 		    return LDNS_STATUS_EMPTY_LABEL;
5917b5038d7SDag-Erling Smørgrav                 }
5927b5038d7SDag-Erling Smørgrav                 *p = *s;
5937b5038d7SDag-Erling Smørgrav                 (*length)++;
5947b5038d7SDag-Erling Smørgrav                 break;
5957b5038d7SDag-Erling Smørgrav             case '\\':
5967b5038d7SDag-Erling Smørgrav                 if ('0' <= s[1] && s[1] <= '9' &&
5977b5038d7SDag-Erling Smørgrav                     '0' <= s[2] && s[2] <= '9' &&
5987b5038d7SDag-Erling Smørgrav                     '0' <= s[3] && s[3] <= '9') {
5997b5038d7SDag-Erling Smørgrav                     /* \DDD seen */
6007b5038d7SDag-Erling Smørgrav                     int val = ((s[1] - '0') * 100 +
6017b5038d7SDag-Erling Smørgrav                            (s[2] - '0') * 10 + (s[3] - '0'));
6027b5038d7SDag-Erling Smørgrav 
6037b5038d7SDag-Erling Smørgrav                     if (0 <= val && val <= 255) {
6047b5038d7SDag-Erling Smørgrav                         /* this also handles \0 */
6057b5038d7SDag-Erling Smørgrav                         s += 3;
6067b5038d7SDag-Erling Smørgrav                         *p = val;
6077b5038d7SDag-Erling Smørgrav                         (*length)++;
6087b5038d7SDag-Erling Smørgrav                     } else {
6097b5038d7SDag-Erling Smørgrav                         return LDNS_STATUS_DDD_OVERFLOW;
6107b5038d7SDag-Erling Smørgrav                     }
6117b5038d7SDag-Erling Smørgrav                 } else {
6127b5038d7SDag-Erling Smørgrav                     /* an espaced character, like \<space> ?
6137b5038d7SDag-Erling Smørgrav                     * remove the '\' keep the rest */
6147b5038d7SDag-Erling Smørgrav                     *p = *++s;
6157b5038d7SDag-Erling Smørgrav                     (*length)++;
6167b5038d7SDag-Erling Smørgrav                 }
6177b5038d7SDag-Erling Smørgrav                 break;
6187b5038d7SDag-Erling Smørgrav             case '\"':
6197b5038d7SDag-Erling Smørgrav                 /* non quoted " Is either first or the last character in
6207b5038d7SDag-Erling Smørgrav                  * the string */
6217b5038d7SDag-Erling Smørgrav 
6227b5038d7SDag-Erling Smørgrav                 *p = *++s; /* skip it */
6237b5038d7SDag-Erling Smørgrav                 (*length)++;
6247b5038d7SDag-Erling Smørgrav 		/* I'm not sure if this is needed in libdns... MG */
6257b5038d7SDag-Erling Smørgrav                 if ( *s == '\0' ) {
6267b5038d7SDag-Erling Smørgrav                     /* ok, it was the last one */
6277b5038d7SDag-Erling Smørgrav                     *p  = '\0';
6287b5038d7SDag-Erling Smørgrav 		    return LDNS_STATUS_OK;
6297b5038d7SDag-Erling Smørgrav                 }
6307b5038d7SDag-Erling Smørgrav                 break;
6317b5038d7SDag-Erling Smørgrav             default:
6327b5038d7SDag-Erling Smørgrav                 *p = *s;
6337b5038d7SDag-Erling Smørgrav                 (*length)++;
6347b5038d7SDag-Erling Smørgrav                 break;
6357b5038d7SDag-Erling Smørgrav         }
6367b5038d7SDag-Erling Smørgrav     }
6377b5038d7SDag-Erling Smørgrav     *p = '\0';
6387b5038d7SDag-Erling Smørgrav     return LDNS_STATUS_OK;
6397b5038d7SDag-Erling Smørgrav }
6407b5038d7SDag-Erling Smørgrav 
6417b5038d7SDag-Erling Smørgrav int
6427b5038d7SDag-Erling Smørgrav ldns_rdf_compare(const ldns_rdf *rd1, const ldns_rdf *rd2)
6437b5038d7SDag-Erling Smørgrav {
6447b5038d7SDag-Erling Smørgrav 	uint16_t i1, i2, i;
6457b5038d7SDag-Erling Smørgrav 	uint8_t *d1, *d2;
6467b5038d7SDag-Erling Smørgrav 
6477b5038d7SDag-Erling Smørgrav 	/* only when both are not NULL we can say anything about them */
6487b5038d7SDag-Erling Smørgrav 	if (!rd1 && !rd2) {
6497b5038d7SDag-Erling Smørgrav 		return 0;
6507b5038d7SDag-Erling Smørgrav 	}
6517b5038d7SDag-Erling Smørgrav 	if (!rd1 || !rd2) {
6527b5038d7SDag-Erling Smørgrav 		return -1;
6537b5038d7SDag-Erling Smørgrav 	}
6547b5038d7SDag-Erling Smørgrav 	i1 = ldns_rdf_size(rd1);
6557b5038d7SDag-Erling Smørgrav 	i2 = ldns_rdf_size(rd2);
6567b5038d7SDag-Erling Smørgrav 
6577b5038d7SDag-Erling Smørgrav 	if (i1 < i2) {
6587b5038d7SDag-Erling Smørgrav 		return -1;
6597b5038d7SDag-Erling Smørgrav 	} else if (i1 > i2) {
6607b5038d7SDag-Erling Smørgrav 		return +1;
6617b5038d7SDag-Erling Smørgrav 	} else {
6627b5038d7SDag-Erling Smørgrav 		d1 = (uint8_t*)ldns_rdf_data(rd1);
6637b5038d7SDag-Erling Smørgrav 		d2 = (uint8_t*)ldns_rdf_data(rd2);
6647b5038d7SDag-Erling Smørgrav 		for(i = 0; i < i1; i++) {
6657b5038d7SDag-Erling Smørgrav 			if (d1[i] < d2[i]) {
6667b5038d7SDag-Erling Smørgrav 				return -1;
6677b5038d7SDag-Erling Smørgrav 			} else if (d1[i] > d2[i]) {
6687b5038d7SDag-Erling Smørgrav 				return +1;
6697b5038d7SDag-Erling Smørgrav 			}
6707b5038d7SDag-Erling Smørgrav 		}
6717b5038d7SDag-Erling Smørgrav 	}
6727b5038d7SDag-Erling Smørgrav 	return 0;
6737b5038d7SDag-Erling Smørgrav }
6747b5038d7SDag-Erling Smørgrav 
6757b5038d7SDag-Erling Smørgrav uint32_t
6767b5038d7SDag-Erling Smørgrav ldns_str2period(const char *nptr, const char **endptr)
6777b5038d7SDag-Erling Smørgrav {
6787b5038d7SDag-Erling Smørgrav 	int sign = 0;
6797b5038d7SDag-Erling Smørgrav 	uint32_t i = 0;
6807b5038d7SDag-Erling Smørgrav 	uint32_t seconds = 0;
6817b5038d7SDag-Erling Smørgrav 
6827b5038d7SDag-Erling Smørgrav 	for(*endptr = nptr; **endptr; (*endptr)++) {
6837b5038d7SDag-Erling Smørgrav 		switch (**endptr) {
6847b5038d7SDag-Erling Smørgrav 			case ' ':
6857b5038d7SDag-Erling Smørgrav 			case '\t':
6867b5038d7SDag-Erling Smørgrav 				break;
6877b5038d7SDag-Erling Smørgrav 			case '-':
6887b5038d7SDag-Erling Smørgrav 				if(sign == 0) {
6897b5038d7SDag-Erling Smørgrav 					sign = -1;
6907b5038d7SDag-Erling Smørgrav 				} else {
6917b5038d7SDag-Erling Smørgrav 					return seconds;
6927b5038d7SDag-Erling Smørgrav 				}
6937b5038d7SDag-Erling Smørgrav 				break;
6947b5038d7SDag-Erling Smørgrav 			case '+':
6957b5038d7SDag-Erling Smørgrav 				if(sign == 0) {
6967b5038d7SDag-Erling Smørgrav 					sign = 1;
6977b5038d7SDag-Erling Smørgrav 				} else {
6987b5038d7SDag-Erling Smørgrav 					return seconds;
6997b5038d7SDag-Erling Smørgrav 				}
7007b5038d7SDag-Erling Smørgrav 				break;
7017b5038d7SDag-Erling Smørgrav 			case 's':
7027b5038d7SDag-Erling Smørgrav 			case 'S':
7037b5038d7SDag-Erling Smørgrav 				seconds += i;
7047b5038d7SDag-Erling Smørgrav 				i = 0;
7057b5038d7SDag-Erling Smørgrav 				break;
7067b5038d7SDag-Erling Smørgrav 			case 'm':
7077b5038d7SDag-Erling Smørgrav 			case 'M':
7087b5038d7SDag-Erling Smørgrav 				seconds += i * 60;
7097b5038d7SDag-Erling Smørgrav 				i = 0;
7107b5038d7SDag-Erling Smørgrav 				break;
7117b5038d7SDag-Erling Smørgrav 			case 'h':
7127b5038d7SDag-Erling Smørgrav 			case 'H':
7137b5038d7SDag-Erling Smørgrav 				seconds += i * 60 * 60;
7147b5038d7SDag-Erling Smørgrav 				i = 0;
7157b5038d7SDag-Erling Smørgrav 				break;
7167b5038d7SDag-Erling Smørgrav 			case 'd':
7177b5038d7SDag-Erling Smørgrav 			case 'D':
7187b5038d7SDag-Erling Smørgrav 				seconds += i * 60 * 60 * 24;
7197b5038d7SDag-Erling Smørgrav 				i = 0;
7207b5038d7SDag-Erling Smørgrav 				break;
7217b5038d7SDag-Erling Smørgrav 			case 'w':
7227b5038d7SDag-Erling Smørgrav 			case 'W':
7237b5038d7SDag-Erling Smørgrav 				seconds += i * 60 * 60 * 24 * 7;
7247b5038d7SDag-Erling Smørgrav 				i = 0;
7257b5038d7SDag-Erling Smørgrav 				break;
7267b5038d7SDag-Erling Smørgrav 			case '0':
7277b5038d7SDag-Erling Smørgrav 			case '1':
7287b5038d7SDag-Erling Smørgrav 			case '2':
7297b5038d7SDag-Erling Smørgrav 			case '3':
7307b5038d7SDag-Erling Smørgrav 			case '4':
7317b5038d7SDag-Erling Smørgrav 			case '5':
7327b5038d7SDag-Erling Smørgrav 			case '6':
7337b5038d7SDag-Erling Smørgrav 			case '7':
7347b5038d7SDag-Erling Smørgrav 			case '8':
7357b5038d7SDag-Erling Smørgrav 			case '9':
7367b5038d7SDag-Erling Smørgrav 				i *= 10;
7377b5038d7SDag-Erling Smørgrav 				i += (**endptr - '0');
7387b5038d7SDag-Erling Smørgrav 				break;
7397b5038d7SDag-Erling Smørgrav 			default:
7407b5038d7SDag-Erling Smørgrav 				seconds += i;
7417b5038d7SDag-Erling Smørgrav 				/* disregard signedness */
7427b5038d7SDag-Erling Smørgrav 				return seconds;
7437b5038d7SDag-Erling Smørgrav 		}
7447b5038d7SDag-Erling Smørgrav 	}
7457b5038d7SDag-Erling Smørgrav 	seconds += i;
7467b5038d7SDag-Erling Smørgrav 	/* disregard signedness */
7477b5038d7SDag-Erling Smørgrav 	return seconds;
7487b5038d7SDag-Erling Smørgrav }
749