1 /**
2  * Copy an uncompressed domain name from a message.
3  *
4  * The caller must allocate at least #WDNS_MAXLEN_NAME bytes for
5  * the destination buffer.
6  *
7  * \param[in] p pointer to message
8  * \param[in] eop pointer to end of message
9  * \param[in] src pointer to domain name
10  * \param[out] dst caller-allocated buffer for domain name
11  * \param[out] sz total length of domain name (may be NULL)
12  *
13  * \return
14  */
15 
16 wdns_res
wdns_copy_uname(const uint8_t * p,const uint8_t * eop,const uint8_t * src,uint8_t * dst,size_t * sz)17 wdns_copy_uname(const uint8_t *p, const uint8_t *eop, const uint8_t *src,
18 		uint8_t *dst, size_t *sz)
19 {
20 	uint8_t c;
21 
22 	size_t total_len = 0;
23 
24 	if (p >= eop || src >= eop || src < p)
25 		return (wdns_res_out_of_bounds);
26 
27 	while ((c = *src++) != 0) {
28 		if (c <= 63) {
29 			total_len++;
30 			if (total_len >= WDNS_MAXLEN_NAME)
31 				return (wdns_res_name_overflow);
32 			*dst++ = c;
33 
34 			total_len += c;
35 			if (total_len >= WDNS_MAXLEN_NAME)
36 				return (wdns_res_name_overflow);
37 			if (src + c > eop)
38 				return (wdns_res_out_of_bounds);
39 			memcpy(dst, src, c);
40 
41 			dst += c;
42 			src += c;
43 		} else {
44 			return (wdns_res_invalid_length_octet);
45 		}
46 	}
47 	*dst = '\0';
48 	total_len++;
49 
50 	if (sz)
51 		*sz = total_len;
52 	return (wdns_res_success);
53 }
54