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