xref: /netbsd-src/lib/libbluetooth/sdp_data.c (revision e057b2281aca041d3f7988132b436b52e1247afe)
1*e057b228Sjoerg /*	$NetBSD: sdp_data.c,v 1.4 2012/03/22 23:46:49 joerg Exp $	*/
2dfbf818aSplunky 
3dfbf818aSplunky /*-
4dfbf818aSplunky  * Copyright (c) 2009 The NetBSD Foundation, Inc.
5dfbf818aSplunky  * All rights reserved.
6dfbf818aSplunky  *
7dfbf818aSplunky  * This code is derived from software contributed to The NetBSD Foundation
8dfbf818aSplunky  * by Iain Hibbert.
9dfbf818aSplunky  *
10dfbf818aSplunky  * Redistribution and use in source and binary forms, with or without
11dfbf818aSplunky  * modification, are permitted provided that the following conditions
12dfbf818aSplunky  * are met:
13dfbf818aSplunky  * 1. Redistributions of source code must retain the above copyright
14dfbf818aSplunky  *    notice, this list of conditions and the following disclaimer.
15dfbf818aSplunky  * 2. Redistributions in binary form must reproduce the above copyright
16dfbf818aSplunky  *    notice, this list of conditions and the following disclaimer in the
17dfbf818aSplunky  *    documentation and/or other materials provided with the distribution.
18dfbf818aSplunky  *
19dfbf818aSplunky  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20dfbf818aSplunky  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21dfbf818aSplunky  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22dfbf818aSplunky  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23dfbf818aSplunky  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24dfbf818aSplunky  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25dfbf818aSplunky  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26dfbf818aSplunky  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27dfbf818aSplunky  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28dfbf818aSplunky  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29dfbf818aSplunky  * POSSIBILITY OF SUCH DAMAGE.
30dfbf818aSplunky  */
31dfbf818aSplunky 
32dfbf818aSplunky #include <sys/cdefs.h>
33*e057b228Sjoerg __RCSID("$NetBSD: sdp_data.c,v 1.4 2012/03/22 23:46:49 joerg Exp $");
34dfbf818aSplunky 
35dfbf818aSplunky #include <sdp.h>
36dfbf818aSplunky #include <stdarg.h>
37dfbf818aSplunky #include <stdio.h>
38dfbf818aSplunky #include <vis.h>
39dfbf818aSplunky 
40dfbf818aSplunky #include "sdp-int.h"
41dfbf818aSplunky 
42dfbf818aSplunky 
43dfbf818aSplunky /******************************************************************************
44dfbf818aSplunky  *	sdp_data_type(data)
45dfbf818aSplunky  *
46dfbf818aSplunky  * return SDP data element type
47dfbf818aSplunky  */
48dfbf818aSplunky int
sdp_data_type(const sdp_data_t * data)49dfbf818aSplunky sdp_data_type(const sdp_data_t *data)
50dfbf818aSplunky {
51dfbf818aSplunky 
52dfbf818aSplunky 	if (data->next + 1 > data->end)
53dfbf818aSplunky 		return -1;
54dfbf818aSplunky 
55dfbf818aSplunky 	return data->next[0];
56dfbf818aSplunky }
57dfbf818aSplunky 
58dfbf818aSplunky 
59dfbf818aSplunky /******************************************************************************
60dfbf818aSplunky  *	sdp_data_size(data)
61dfbf818aSplunky  *
62dfbf818aSplunky  * return the size of SDP data element. This will fail (return -1) if
63dfbf818aSplunky  * the data element does not fit into the data space.
64dfbf818aSplunky  */
65dfbf818aSplunky ssize_t
sdp_data_size(const sdp_data_t * data)66dfbf818aSplunky sdp_data_size(const sdp_data_t *data)
67dfbf818aSplunky {
68dfbf818aSplunky 	uint8_t *p = data->next;
69dfbf818aSplunky 
70dfbf818aSplunky 	if (p + 1 > data->end)
71dfbf818aSplunky 		return -1;
72dfbf818aSplunky 
73dfbf818aSplunky 	switch (*p++) {
74dfbf818aSplunky 	case SDP_DATA_NIL:
75dfbf818aSplunky 		break;
76dfbf818aSplunky 
77dfbf818aSplunky 	case SDP_DATA_BOOL:
78dfbf818aSplunky 	case SDP_DATA_INT8:
79dfbf818aSplunky 	case SDP_DATA_UINT8:
80dfbf818aSplunky 		p += 1;
81dfbf818aSplunky 		break;
82dfbf818aSplunky 
83dfbf818aSplunky 	case SDP_DATA_INT16:
84dfbf818aSplunky 	case SDP_DATA_UINT16:
85dfbf818aSplunky 	case SDP_DATA_UUID16:
86dfbf818aSplunky 		p += 2;
87dfbf818aSplunky 		break;
88dfbf818aSplunky 
89dfbf818aSplunky 	case SDP_DATA_INT32:
90dfbf818aSplunky 	case SDP_DATA_UINT32:
91dfbf818aSplunky 	case SDP_DATA_UUID32:
92dfbf818aSplunky 		p += 4;
93dfbf818aSplunky 		break;
94dfbf818aSplunky 
95dfbf818aSplunky 	case SDP_DATA_INT64:
96dfbf818aSplunky 	case SDP_DATA_UINT64:
97dfbf818aSplunky 		p += 8;
98dfbf818aSplunky 		break;
99dfbf818aSplunky 
100dfbf818aSplunky 	case SDP_DATA_INT128:
101dfbf818aSplunky 	case SDP_DATA_UINT128:
102dfbf818aSplunky 	case SDP_DATA_UUID128:
103dfbf818aSplunky 		p += 16;
104dfbf818aSplunky 		break;
105dfbf818aSplunky 
106dfbf818aSplunky 	case SDP_DATA_ALT8:
107dfbf818aSplunky 	case SDP_DATA_SEQ8:
108dfbf818aSplunky 	case SDP_DATA_STR8:
109dfbf818aSplunky 	case SDP_DATA_URL8:
110dfbf818aSplunky 		if (p + 1 > data->end)
111dfbf818aSplunky 			return -1;
112dfbf818aSplunky 
113dfbf818aSplunky 		p += 1 + *p;
114dfbf818aSplunky 		break;
115dfbf818aSplunky 
116dfbf818aSplunky 	case SDP_DATA_ALT16:
117dfbf818aSplunky 	case SDP_DATA_SEQ16:
118dfbf818aSplunky 	case SDP_DATA_STR16:
119dfbf818aSplunky 	case SDP_DATA_URL16:
120dfbf818aSplunky 		if (p + 2 > data->end)
121dfbf818aSplunky 			return -1;
122dfbf818aSplunky 
123dfbf818aSplunky 		p += 2 + be16dec(p);
124dfbf818aSplunky 		break;
125dfbf818aSplunky 
126dfbf818aSplunky 	case SDP_DATA_ALT32:
127dfbf818aSplunky 	case SDP_DATA_SEQ32:
128dfbf818aSplunky 	case SDP_DATA_STR32:
129dfbf818aSplunky 	case SDP_DATA_URL32:
130dfbf818aSplunky 		if (p + 4 > data->end)
131dfbf818aSplunky 			return -1;
132dfbf818aSplunky 
133dfbf818aSplunky 		p += 4 + be32dec(p);
134dfbf818aSplunky 		break;
135dfbf818aSplunky 
136dfbf818aSplunky 	default:
137dfbf818aSplunky 		return -1;
138dfbf818aSplunky 	}
139dfbf818aSplunky 
140dfbf818aSplunky 	if (p > data->end)
141dfbf818aSplunky 		return -1;
142dfbf818aSplunky 
143dfbf818aSplunky 	return (p - data->next);
144dfbf818aSplunky }
145dfbf818aSplunky 
146dfbf818aSplunky /******************************************************************************
147dfbf818aSplunky  *	sdp_data_valid(data)
148dfbf818aSplunky  *
149dfbf818aSplunky  * validate an SDP data element list recursively, ensuring elements do not
150dfbf818aSplunky  * expand past the claimed length and that there is no invalid data.
151dfbf818aSplunky  */
152dfbf818aSplunky static bool
_sdp_data_valid(uint8_t * ptr,uint8_t * end)153dfbf818aSplunky _sdp_data_valid(uint8_t *ptr, uint8_t *end)
154dfbf818aSplunky {
155dfbf818aSplunky 	size_t len;
156dfbf818aSplunky 
157dfbf818aSplunky 	while (ptr < end) {
158dfbf818aSplunky 		if (ptr + 1 > end)
159dfbf818aSplunky 			return false;
160dfbf818aSplunky 
161dfbf818aSplunky 		switch (*ptr++) {
162dfbf818aSplunky 		case SDP_DATA_NIL:
163dfbf818aSplunky 			break;
164dfbf818aSplunky 
165dfbf818aSplunky 		case SDP_DATA_BOOL:
166dfbf818aSplunky 		case SDP_DATA_INT8:
167dfbf818aSplunky 		case SDP_DATA_UINT8:
168dfbf818aSplunky 			if (ptr + 1 > end)
169dfbf818aSplunky 				return false;
170dfbf818aSplunky 
171dfbf818aSplunky 			ptr += 1;
172dfbf818aSplunky 			break;
173dfbf818aSplunky 
174dfbf818aSplunky 		case SDP_DATA_INT16:
175dfbf818aSplunky 		case SDP_DATA_UINT16:
176dfbf818aSplunky 		case SDP_DATA_UUID16:
177dfbf818aSplunky 			if (ptr + 2 > end)
178dfbf818aSplunky 				return false;
179dfbf818aSplunky 
180dfbf818aSplunky 			ptr += 2;
181dfbf818aSplunky 			break;
182dfbf818aSplunky 
183dfbf818aSplunky 		case SDP_DATA_INT32:
184dfbf818aSplunky 		case SDP_DATA_UINT32:
185dfbf818aSplunky 		case SDP_DATA_UUID32:
186dfbf818aSplunky 			if (ptr + 4 > end)
187dfbf818aSplunky 				return false;
188dfbf818aSplunky 
189dfbf818aSplunky 			ptr += 4;
190dfbf818aSplunky 			break;
191dfbf818aSplunky 
192dfbf818aSplunky 		case SDP_DATA_INT64:
193dfbf818aSplunky 		case SDP_DATA_UINT64:
194dfbf818aSplunky 			if (ptr + 8 > end)
195dfbf818aSplunky 				return false;
196dfbf818aSplunky 
197dfbf818aSplunky 			ptr += 8;
198dfbf818aSplunky 			break;
199dfbf818aSplunky 
200dfbf818aSplunky 		case SDP_DATA_INT128:
201dfbf818aSplunky 		case SDP_DATA_UINT128:
202dfbf818aSplunky 		case SDP_DATA_UUID128:
203dfbf818aSplunky 			if (ptr + 16 > end)
204dfbf818aSplunky 				return false;
205dfbf818aSplunky 
206dfbf818aSplunky 			ptr += 16;
207dfbf818aSplunky 			break;
208dfbf818aSplunky 
209dfbf818aSplunky 		case SDP_DATA_STR8:
210dfbf818aSplunky 		case SDP_DATA_URL8:
211dfbf818aSplunky 			if (ptr + 1 > end)
212dfbf818aSplunky 				return false;
213dfbf818aSplunky 
214dfbf818aSplunky 			len = *ptr;
215dfbf818aSplunky 			ptr += 1;
216dfbf818aSplunky 
217dfbf818aSplunky 			if (ptr + len > end)
218dfbf818aSplunky 				return false;
219dfbf818aSplunky 
220dfbf818aSplunky 			ptr += len;
221dfbf818aSplunky 			break;
222dfbf818aSplunky 
223dfbf818aSplunky 		case SDP_DATA_STR16:
224dfbf818aSplunky 		case SDP_DATA_URL16:
225dfbf818aSplunky 			if (ptr + 2 > end)
226dfbf818aSplunky 				return false;
227dfbf818aSplunky 
228dfbf818aSplunky 			len = be16dec(ptr);
229dfbf818aSplunky 			ptr += 2;
230dfbf818aSplunky 
231dfbf818aSplunky 			if (ptr + len > end)
232dfbf818aSplunky 				return false;
233dfbf818aSplunky 
234dfbf818aSplunky 			ptr += len;
235dfbf818aSplunky 			break;
236dfbf818aSplunky 
237dfbf818aSplunky 		case SDP_DATA_STR32:
238dfbf818aSplunky 		case SDP_DATA_URL32:
239dfbf818aSplunky 			if (ptr + 4 > end)
240dfbf818aSplunky 				return false;
241dfbf818aSplunky 
242dfbf818aSplunky 			len = be32dec(ptr);
243dfbf818aSplunky 			ptr += 4;
244dfbf818aSplunky 
245dfbf818aSplunky 			if (ptr + len > end)
246dfbf818aSplunky 				return false;
247dfbf818aSplunky 
248dfbf818aSplunky 			ptr += len;
249dfbf818aSplunky 			break;
250dfbf818aSplunky 
251dfbf818aSplunky 		case SDP_DATA_SEQ8:
252dfbf818aSplunky 		case SDP_DATA_ALT8:
253dfbf818aSplunky 			if (ptr + 1 > end)
254dfbf818aSplunky 				return false;
255dfbf818aSplunky 
256dfbf818aSplunky 			len = *ptr;
257dfbf818aSplunky 			ptr += 1;
258dfbf818aSplunky 
259dfbf818aSplunky 			if (ptr + len > end)
260dfbf818aSplunky 				return false;
261dfbf818aSplunky 
262dfbf818aSplunky 			if (!_sdp_data_valid(ptr, ptr + len))
263dfbf818aSplunky 				return false;
264dfbf818aSplunky 
265dfbf818aSplunky 			ptr += len;
266dfbf818aSplunky 			break;
267dfbf818aSplunky 
268dfbf818aSplunky 		case SDP_DATA_SEQ16:
269dfbf818aSplunky 		case SDP_DATA_ALT16:
270dfbf818aSplunky 			if (ptr + 2 > end)
271dfbf818aSplunky 				return false;
272dfbf818aSplunky 
273dfbf818aSplunky 			len = be16dec(ptr);
274dfbf818aSplunky 			ptr += 2;
275dfbf818aSplunky 
276dfbf818aSplunky 			if (ptr + len > end)
277dfbf818aSplunky 				return false;
278dfbf818aSplunky 
279dfbf818aSplunky 			if (!_sdp_data_valid(ptr, ptr + len))
280dfbf818aSplunky 				return false;
281dfbf818aSplunky 
282dfbf818aSplunky 			ptr += len;
283dfbf818aSplunky 			break;
284dfbf818aSplunky 
285dfbf818aSplunky 		case SDP_DATA_SEQ32:
286dfbf818aSplunky 		case SDP_DATA_ALT32:
287dfbf818aSplunky 			if (ptr + 4 > end)
288dfbf818aSplunky 				return false;
289dfbf818aSplunky 
290dfbf818aSplunky 			len = be32dec(ptr);
291dfbf818aSplunky 			ptr += 4;
292dfbf818aSplunky 
293dfbf818aSplunky 			if (ptr + len > end)
294dfbf818aSplunky 				return false;
295dfbf818aSplunky 
296dfbf818aSplunky 			if (!_sdp_data_valid(ptr, ptr + len))
297dfbf818aSplunky 				return false;
298dfbf818aSplunky 
299dfbf818aSplunky 			ptr += len;
300dfbf818aSplunky 			break;
301dfbf818aSplunky 
302dfbf818aSplunky 		default:
303dfbf818aSplunky 			return false;
304dfbf818aSplunky 		}
305dfbf818aSplunky 	}
306dfbf818aSplunky 
307dfbf818aSplunky 	return true;
308dfbf818aSplunky }
309dfbf818aSplunky 
310dfbf818aSplunky bool
sdp_data_valid(const sdp_data_t * data)311dfbf818aSplunky sdp_data_valid(const sdp_data_t *data)
312dfbf818aSplunky {
313dfbf818aSplunky 
314dfbf818aSplunky 	if (data->next == NULL || data->end == NULL)
315dfbf818aSplunky 		return false;
316dfbf818aSplunky 
317dfbf818aSplunky 	if (data->next >= data->end)
318dfbf818aSplunky 		return false;
319dfbf818aSplunky 
320dfbf818aSplunky 	return _sdp_data_valid(data->next, data->end);
321dfbf818aSplunky }
322dfbf818aSplunky 
323dfbf818aSplunky /******************************************************************************
324dfbf818aSplunky  *	sdp_data_print(data, indent)
325dfbf818aSplunky  *
326dfbf818aSplunky  * print out a SDP data element list in human readable format
327dfbf818aSplunky  */
328*e057b228Sjoerg static __printflike(3, 4) void
_sdp_put(int indent,const char * type,const char * fmt,...)329dfbf818aSplunky _sdp_put(int indent, const char *type, const char *fmt, ...)
330dfbf818aSplunky {
331dfbf818aSplunky 	va_list ap;
332dfbf818aSplunky 
333dfbf818aSplunky 	indent = printf("%*s%s", indent, "", type);
334dfbf818aSplunky 	indent = 18 - indent;
335dfbf818aSplunky 	if (indent < 2)
336dfbf818aSplunky 		indent = 2;
337dfbf818aSplunky 
338dfbf818aSplunky 	printf("%*s", indent, "");
339dfbf818aSplunky 
340dfbf818aSplunky 	va_start(ap, fmt);
341dfbf818aSplunky 	vprintf(fmt, ap);
342dfbf818aSplunky 	va_end(ap);
343dfbf818aSplunky 
344dfbf818aSplunky 	printf("\n");
345dfbf818aSplunky }
346dfbf818aSplunky 
347dfbf818aSplunky static void
_sdp_putstr(int indent,const char * type,const uint8_t * str,size_t len)34860e46d91Splunky _sdp_putstr(int indent, const char *type, const uint8_t *str, size_t len)
349dfbf818aSplunky {
350dfbf818aSplunky 	char buf[50], *dst = buf;
35160e46d91Splunky 	int style;
352dfbf818aSplunky 
353dfbf818aSplunky 	indent = printf("%*s%s(%zu)", indent, "", type, len);
354dfbf818aSplunky 	indent = 18 - indent;
355dfbf818aSplunky 	if (indent < 2)
356dfbf818aSplunky 		indent = 2;
357dfbf818aSplunky 
358dfbf818aSplunky 	printf("%*s", indent, "");
359dfbf818aSplunky 
36060e46d91Splunky 	style = VIS_CSTYLE | VIS_NL;
3619bc458e1Splunky 	buf[0] = '\0';
362dfbf818aSplunky 
363dfbf818aSplunky 	while (len > 0 && (dst + 5) < (buf + sizeof(buf))) {
364dfbf818aSplunky 		dst = vis(dst, str[0], style, (len > 0 ? str[1] : 0));
365dfbf818aSplunky 		str++;
366dfbf818aSplunky 		len--;
367dfbf818aSplunky 	}
368dfbf818aSplunky 
369dfbf818aSplunky 	printf("\"%s%s\n", buf, (len == 0 ? "\"" : " ..."));
370dfbf818aSplunky }
371dfbf818aSplunky 
372dfbf818aSplunky bool
_sdp_data_print(const uint8_t * next,const uint8_t * end,int indent)373dfbf818aSplunky _sdp_data_print(const uint8_t *next, const uint8_t *end, int indent)
374dfbf818aSplunky {
375dfbf818aSplunky 	size_t len;
376dfbf818aSplunky 
377dfbf818aSplunky 	while (next < end) {
378dfbf818aSplunky 		if (next + 1 > end)
379dfbf818aSplunky 			return false;
380dfbf818aSplunky 
381dfbf818aSplunky 		switch (*next++) {
382dfbf818aSplunky 		case SDP_DATA_NIL:
383dfbf818aSplunky 			_sdp_put(indent, "nil", "");
384dfbf818aSplunky 			break;
385dfbf818aSplunky 
386dfbf818aSplunky 		case SDP_DATA_BOOL:
387dfbf818aSplunky 			if (next + 1 > end)
388dfbf818aSplunky 				return false;
389dfbf818aSplunky 
390dfbf818aSplunky 			_sdp_put(indent, "bool", "%s",
391dfbf818aSplunky 			    (*next == 0x00 ? "false" : "true"));
392dfbf818aSplunky 
393dfbf818aSplunky 			next += 1;
394dfbf818aSplunky 			break;
395dfbf818aSplunky 
396dfbf818aSplunky 		case SDP_DATA_INT8:
397dfbf818aSplunky 			if (next + 1 > end)
398dfbf818aSplunky 				return false;
399dfbf818aSplunky 
400dfbf818aSplunky 			_sdp_put(indent, "int8", "%" PRId8,
401dfbf818aSplunky 			    *(const int8_t *)next);
402dfbf818aSplunky 			next += 1;
403dfbf818aSplunky 			break;
404dfbf818aSplunky 
405dfbf818aSplunky 		case SDP_DATA_UINT8:
406dfbf818aSplunky 			if (next + 1 > end)
407dfbf818aSplunky 				return false;
408dfbf818aSplunky 
409dfbf818aSplunky 			_sdp_put(indent, "uint8", "0x%02" PRIx8,
410dfbf818aSplunky 			    *next);
411dfbf818aSplunky 			next += 1;
412dfbf818aSplunky 			break;
413dfbf818aSplunky 
414dfbf818aSplunky 		case SDP_DATA_INT16:
415dfbf818aSplunky 			if (next + 2 > end)
416dfbf818aSplunky 				return false;
417dfbf818aSplunky 
418dfbf818aSplunky 			_sdp_put(indent, "int16", "%" PRId16,
419dfbf818aSplunky 			    (int16_t)be16dec(next));
420dfbf818aSplunky 			next += 2;
421dfbf818aSplunky 			break;
422dfbf818aSplunky 
423dfbf818aSplunky 		case SDP_DATA_UINT16:
424dfbf818aSplunky 			if (next + 2 > end)
425dfbf818aSplunky 				return false;
426dfbf818aSplunky 
427dfbf818aSplunky 			_sdp_put(indent, "uint16", "0x%04" PRIx16,
428dfbf818aSplunky 			    be16dec(next));
429dfbf818aSplunky 			next += 2;
430dfbf818aSplunky 			break;
431dfbf818aSplunky 
432dfbf818aSplunky 		case SDP_DATA_UUID16:
433dfbf818aSplunky 			if (next + 2 > end)
434dfbf818aSplunky 				return false;
435dfbf818aSplunky 
436dfbf818aSplunky 			_sdp_put(indent, "uuid16", "0x%04" PRIx16,
437dfbf818aSplunky 			    be16dec(next));
438dfbf818aSplunky 			next += 2;
439dfbf818aSplunky 			break;
440dfbf818aSplunky 
441dfbf818aSplunky 		case SDP_DATA_INT32:
442dfbf818aSplunky 			if (next + 4 > end)
443dfbf818aSplunky 				return false;
444dfbf818aSplunky 
445dfbf818aSplunky 			_sdp_put(indent, "int32", "%" PRId32,
446dfbf818aSplunky 			    (int32_t)be32dec(next));
447dfbf818aSplunky 			next += 4;
448dfbf818aSplunky 			break;
449dfbf818aSplunky 
450dfbf818aSplunky 		case SDP_DATA_UINT32:
451dfbf818aSplunky 			if (next + 4 > end)
452dfbf818aSplunky 				return false;
453dfbf818aSplunky 
454dfbf818aSplunky 			_sdp_put(indent, "uint32", "0x%08" PRIx32,
455dfbf818aSplunky 			    be32dec(next));
456dfbf818aSplunky 			next += 4;
457dfbf818aSplunky 			break;
458dfbf818aSplunky 
459dfbf818aSplunky 		case SDP_DATA_UUID32:
460dfbf818aSplunky 			if (next + 4 > end)
461dfbf818aSplunky 				return false;
462dfbf818aSplunky 
463dfbf818aSplunky 			_sdp_put(indent, "uuid32", "0x%08" PRIx32,
464dfbf818aSplunky 			    be32dec(next));
465dfbf818aSplunky 			next += 4;
466dfbf818aSplunky 			break;
467dfbf818aSplunky 
468dfbf818aSplunky 		case SDP_DATA_INT64:
469dfbf818aSplunky 			if (next + 8 > end)
470dfbf818aSplunky 				return false;
471dfbf818aSplunky 
472dfbf818aSplunky 			_sdp_put(indent, "int64", "%" PRId64,
473dfbf818aSplunky 			    (int64_t)be64dec(next));
474dfbf818aSplunky 			next += 8;
475dfbf818aSplunky 			break;
476dfbf818aSplunky 
477dfbf818aSplunky 		case SDP_DATA_UINT64:
478dfbf818aSplunky 			if (next + 8 > end)
479dfbf818aSplunky 				return false;
480dfbf818aSplunky 
481dfbf818aSplunky 			_sdp_put(indent, "uint64", "0x%016" PRIx64,
482dfbf818aSplunky 			    be64dec(next));
483dfbf818aSplunky 			next += 8;
484dfbf818aSplunky 			break;
485dfbf818aSplunky 
486dfbf818aSplunky 		case SDP_DATA_INT128:
487dfbf818aSplunky 			if (next + 16 > end)
488dfbf818aSplunky 				return false;
489dfbf818aSplunky 
490dfbf818aSplunky 			_sdp_put(indent, "int128",
491dfbf818aSplunky 				"0x%02x%02x%02x%02x%02x%02x%02x%02x"
492dfbf818aSplunky 				"%02x%02x%02x%02x%02x%02x%02x%02x",
493dfbf818aSplunky 				next[0], next[1], next[2], next[3],
494dfbf818aSplunky 				next[4], next[5], next[6], next[7],
495dfbf818aSplunky 				next[8], next[9], next[10], next[11],
496dfbf818aSplunky 				next[12], next[13], next[14], next[15]);
497dfbf818aSplunky 			next += 16;
498dfbf818aSplunky 			break;
499dfbf818aSplunky 
500dfbf818aSplunky 		case SDP_DATA_UINT128:
501dfbf818aSplunky 			if (next + 16 > end)
502dfbf818aSplunky 				return false;
503dfbf818aSplunky 
504dfbf818aSplunky 			_sdp_put(indent, "uint128",
505dfbf818aSplunky 				"0x%02x%02x%02x%02x%02x%02x%02x%02x"
506dfbf818aSplunky 				"%02x%02x%02x%02x%02x%02x%02x%02x",
507dfbf818aSplunky 				next[0], next[1], next[2], next[3],
508dfbf818aSplunky 				next[4], next[5], next[6], next[7],
509dfbf818aSplunky 				next[8], next[9], next[10], next[11],
510dfbf818aSplunky 				next[12], next[13], next[14], next[15]);
511dfbf818aSplunky 			next += 16;
512dfbf818aSplunky 			break;
513dfbf818aSplunky 
514dfbf818aSplunky 		case SDP_DATA_UUID128:
515dfbf818aSplunky 			if (next + 16 > end)
516dfbf818aSplunky 				return false;
517dfbf818aSplunky 
518dfbf818aSplunky 			_sdp_put(indent, "uuid128",
519dfbf818aSplunky 				"%02x%02x%02x%02x-"
520dfbf818aSplunky 				"%02x%02x-"
521dfbf818aSplunky 				"%02x%02x-"
522dfbf818aSplunky 				"%02x%02x-"
523dfbf818aSplunky 				"%02x%02x%02x%02x%02x%02x",
524dfbf818aSplunky 				next[0], next[1], next[2], next[3],
525dfbf818aSplunky 				next[4], next[5],
526dfbf818aSplunky 				next[6], next[7],
527dfbf818aSplunky 				next[8], next[9],
528dfbf818aSplunky 				next[10], next[11], next[12],
529dfbf818aSplunky 				next[13], next[14], next[15]);
530dfbf818aSplunky 			next += 16;
531dfbf818aSplunky 			break;
532dfbf818aSplunky 
533dfbf818aSplunky 		case SDP_DATA_STR8:
534dfbf818aSplunky 			if (next + 1 > end)
535dfbf818aSplunky 				return false;
536dfbf818aSplunky 
537dfbf818aSplunky 			len = *next;
538dfbf818aSplunky 			next += 1;
539dfbf818aSplunky 
540dfbf818aSplunky 			if (next + len > end)
541dfbf818aSplunky 				return false;
542dfbf818aSplunky 
54360e46d91Splunky 			_sdp_putstr(indent, "str8", next, len);
544dfbf818aSplunky 			next += len;
545dfbf818aSplunky 			break;
546dfbf818aSplunky 
547dfbf818aSplunky 		case SDP_DATA_URL8:
548dfbf818aSplunky 			if (next + 1 > end)
549dfbf818aSplunky 				return false;
550dfbf818aSplunky 
551dfbf818aSplunky 			len = *next;
552dfbf818aSplunky 			next += 1;
553dfbf818aSplunky 
554dfbf818aSplunky 			if (next + len > end)
555dfbf818aSplunky 				return false;
556dfbf818aSplunky 
55760e46d91Splunky 			_sdp_putstr(indent, "url8", next, len);
558dfbf818aSplunky 			next += len;
559dfbf818aSplunky 			break;
560dfbf818aSplunky 
561dfbf818aSplunky 		case SDP_DATA_STR16:
562dfbf818aSplunky 			if (next + 2 > end)
563dfbf818aSplunky 				return false;
564dfbf818aSplunky 
565dfbf818aSplunky 			len = be16dec(next);
566dfbf818aSplunky 			next += 2;
567dfbf818aSplunky 
568dfbf818aSplunky 			if (next + len > end)
569dfbf818aSplunky 				return false;
570dfbf818aSplunky 
57160e46d91Splunky 			_sdp_putstr(indent, "str16", next, len);
572dfbf818aSplunky 			next += len;
573dfbf818aSplunky 			break;
574dfbf818aSplunky 
575dfbf818aSplunky 		case SDP_DATA_URL16:
576dfbf818aSplunky 			if (next + 2 > end)
577dfbf818aSplunky 				return false;
578dfbf818aSplunky 
579dfbf818aSplunky 			len = be16dec(next);
580dfbf818aSplunky 			next += 2;
581dfbf818aSplunky 
582dfbf818aSplunky 			if (next + len > end)
583dfbf818aSplunky 				return false;
584dfbf818aSplunky 
58560e46d91Splunky 			_sdp_putstr(indent, "url16", next, len);
586dfbf818aSplunky 			next += len;
587dfbf818aSplunky 			break;
588dfbf818aSplunky 
589dfbf818aSplunky 		case SDP_DATA_STR32:
590dfbf818aSplunky 			if (next + 4 > end)
591dfbf818aSplunky 				return false;
592dfbf818aSplunky 
593dfbf818aSplunky 			len = be32dec(next);
594dfbf818aSplunky 			next += 4;
595dfbf818aSplunky 
596dfbf818aSplunky 			if (next + len > end)
597dfbf818aSplunky 				return false;
598dfbf818aSplunky 
59960e46d91Splunky 			_sdp_putstr(indent, "str32", next, len);
600dfbf818aSplunky 			next += len;
601dfbf818aSplunky 			break;
602dfbf818aSplunky 
603dfbf818aSplunky 		case SDP_DATA_URL32:
604dfbf818aSplunky 			if (next + 4 > end)
605dfbf818aSplunky 				return false;
606dfbf818aSplunky 
607dfbf818aSplunky 			len = be32dec(next);
608dfbf818aSplunky 			next += 4;
609dfbf818aSplunky 
610dfbf818aSplunky 			if (next + len > end)
611dfbf818aSplunky 				return false;
612dfbf818aSplunky 
61360e46d91Splunky 			_sdp_putstr(indent, "url32", next, len);
614dfbf818aSplunky 			next += len;
615dfbf818aSplunky 			break;
616dfbf818aSplunky 
617dfbf818aSplunky 		case SDP_DATA_SEQ8:
618dfbf818aSplunky 			if (next + 1 > end)
619dfbf818aSplunky 				return false;
620dfbf818aSplunky 
621dfbf818aSplunky 			len = *next;
622dfbf818aSplunky 			next += 1;
623dfbf818aSplunky 
624dfbf818aSplunky 			if (next + len > end)
625dfbf818aSplunky 				return false;
626dfbf818aSplunky 
627dfbf818aSplunky 			printf("%*sseq8(%zu)\n", indent, "", len);
628dfbf818aSplunky 			if (!_sdp_data_print(next, next + len, indent + 1))
629dfbf818aSplunky 				return false;
630dfbf818aSplunky 
631dfbf818aSplunky 			next += len;
632dfbf818aSplunky 			break;
633dfbf818aSplunky 
634dfbf818aSplunky 		case SDP_DATA_ALT8:
635dfbf818aSplunky 			if (next + 1 > end)
636dfbf818aSplunky 				return false;
637dfbf818aSplunky 
638dfbf818aSplunky 			len = *next;
639dfbf818aSplunky 			next += 1;
640dfbf818aSplunky 
641dfbf818aSplunky 			if (next + len > end)
642dfbf818aSplunky 				return false;
643dfbf818aSplunky 
644dfbf818aSplunky 			printf("%*salt8(%zu)\n", indent, "", len);
645dfbf818aSplunky 			if (!_sdp_data_print(next, next + len, indent + 1))
646dfbf818aSplunky 				return false;
647dfbf818aSplunky 
648dfbf818aSplunky 			next += len;
649dfbf818aSplunky 			break;
650dfbf818aSplunky 
651dfbf818aSplunky 		case SDP_DATA_SEQ16:
652dfbf818aSplunky 			if (next + 2 > end)
653dfbf818aSplunky 				return false;
654dfbf818aSplunky 
655dfbf818aSplunky 			len = be16dec(next);
656dfbf818aSplunky 			next += 2;
657dfbf818aSplunky 
658dfbf818aSplunky 			if (next + len > end)
659dfbf818aSplunky 				return false;
660dfbf818aSplunky 
661dfbf818aSplunky 			printf("%*sseq16(%zu)\n", indent, "", len);
662dfbf818aSplunky 			if (!_sdp_data_print(next, next + len, indent + 1))
663dfbf818aSplunky 				return false;
664dfbf818aSplunky 
665dfbf818aSplunky 			next += len;
666dfbf818aSplunky 			break;
667dfbf818aSplunky 
668dfbf818aSplunky 		case SDP_DATA_ALT16:
669dfbf818aSplunky 			if (next + 2 > end)
670dfbf818aSplunky 				return false;
671dfbf818aSplunky 
672dfbf818aSplunky 			len = be16dec(next);
673dfbf818aSplunky 			next += 2;
674dfbf818aSplunky 
675dfbf818aSplunky 			if (next + len > end)
676dfbf818aSplunky 				return false;
677dfbf818aSplunky 
678dfbf818aSplunky 			printf("%*salt16(%zu)\n", indent, "", len);
679dfbf818aSplunky 			if (!_sdp_data_print(next, next + len, indent + 1))
680dfbf818aSplunky 				return false;
681dfbf818aSplunky 
682dfbf818aSplunky 			next += len;
683dfbf818aSplunky 			break;
684dfbf818aSplunky 
685dfbf818aSplunky 		case SDP_DATA_SEQ32:
686dfbf818aSplunky 			if (next + 4 > end)
687dfbf818aSplunky 				return false;
688dfbf818aSplunky 
689dfbf818aSplunky 			len = be32dec(next);
690dfbf818aSplunky 			next += 4;
691dfbf818aSplunky 
692dfbf818aSplunky 			if (next + len > end)
693dfbf818aSplunky 				return false;
694dfbf818aSplunky 
695dfbf818aSplunky 			printf("%*sseq32(%zu)\n", indent, "", len);
696dfbf818aSplunky 			if (!_sdp_data_print(next, next + len, indent + 1))
697dfbf818aSplunky 				return false;
698dfbf818aSplunky 
699dfbf818aSplunky 			next += len;
700dfbf818aSplunky 			break;
701dfbf818aSplunky 
702dfbf818aSplunky 		case SDP_DATA_ALT32:
703dfbf818aSplunky 			if (next + 4 > end)
704dfbf818aSplunky 				return false;
705dfbf818aSplunky 
706dfbf818aSplunky 			len = be32dec(next);
707dfbf818aSplunky 			next += 4;
708dfbf818aSplunky 
709dfbf818aSplunky 			if (next + len > end)
710dfbf818aSplunky 				return false;
711dfbf818aSplunky 
712dfbf818aSplunky 			printf("%*salt32(%zu)\n", indent, "", len);
713dfbf818aSplunky 			if (!_sdp_data_print(next, next + len, indent + 1))
714dfbf818aSplunky 				return false;
715dfbf818aSplunky 
716dfbf818aSplunky 			next += len;
717dfbf818aSplunky 			break;
718dfbf818aSplunky 
719dfbf818aSplunky 		default:
720dfbf818aSplunky 			return false;
721dfbf818aSplunky 		}
722dfbf818aSplunky 	}
723dfbf818aSplunky 
724dfbf818aSplunky 	return true;
725dfbf818aSplunky }
726dfbf818aSplunky 
727dfbf818aSplunky void
sdp_data_print(const sdp_data_t * data,int indent)728dfbf818aSplunky sdp_data_print(const sdp_data_t *data, int indent)
729dfbf818aSplunky {
730dfbf818aSplunky 
731dfbf818aSplunky 	if (!_sdp_data_print(data->next, data->end, indent))
732dfbf818aSplunky 		printf("SDP data error\n");
733dfbf818aSplunky }
734