1 /* $NetBSD: sdp_data.c$ */
4 * Copyright (c) 2009 The NetBSD Foundation, Inc.
7 * This code is derived from software contributed to The NetBSD Foundation
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
32 #include <sys/cdefs.h>
33 __RCSID("$NetBSD: sdp_data.c$");
43 /******************************************************************************
46 * return SDP data element type
49 sdp_data_type(const sdp_data_t
*data
)
52 if (data
->next
+ 1 > data
->end
)
59 /******************************************************************************
62 * return the size of SDP data element. This will fail (return -1) if
63 * the data element does not fit into the data space.
66 sdp_data_size(const sdp_data_t
*data
)
68 uint8_t *p
= data
->next
;
70 if (p
+ 1 > data
->end
)
100 case SDP_DATA_INT128
:
101 case SDP_DATA_UINT128
:
102 case SDP_DATA_UUID128
:
110 if (p
+ 1 > data
->end
)
120 if (p
+ 2 > data
->end
)
130 if (p
+ 4 > data
->end
)
143 return (p
- data
->next
);
146 /******************************************************************************
147 * sdp_data_valid(data)
149 * validate an SDP data element list recursively, ensuring elements do not
150 * expand past the claimed length and that there is no invalid data.
153 _sdp_data_valid(uint8_t *ptr
, uint8_t *end
)
175 case SDP_DATA_UINT16
:
176 case SDP_DATA_UUID16
:
184 case SDP_DATA_UINT32
:
185 case SDP_DATA_UUID32
:
193 case SDP_DATA_UINT64
:
200 case SDP_DATA_INT128
:
201 case SDP_DATA_UINT128
:
202 case SDP_DATA_UUID128
:
262 if (!_sdp_data_valid(ptr
, ptr
+ len
))
279 if (!_sdp_data_valid(ptr
, ptr
+ len
))
296 if (!_sdp_data_valid(ptr
, ptr
+ len
))
311 sdp_data_valid(const sdp_data_t
*data
)
314 if (data
->next
== NULL
|| data
->end
== NULL
)
317 if (data
->next
>= data
->end
)
320 return _sdp_data_valid(data
->next
, data
->end
);
323 /******************************************************************************
324 * sdp_data_print(data, indent)
326 * print out a SDP data element list in human readable format
329 _sdp_put(int indent
, const char *type
, const char *fmt
, ...)
333 indent
= printf("%*s%s", indent
, "", type
);
334 indent
= 18 - indent
;
338 printf("%*s", indent
, "");
348 _sdp_putstr(int indent
, int style
, const char *type
,
349 const uint8_t *str
, size_t len
)
351 char buf
[50], *dst
= buf
;
353 indent
= printf("%*s%s(%zu)", indent
, "", type
, len
);
354 indent
= 18 - indent
;
358 printf("%*s", indent
, "");
362 while (len
> 0 && (dst
+ 5) < (buf
+ sizeof(buf
))) {
363 dst
= vis(dst
, str
[0], style
, (len
> 0 ? str
[1] : 0));
368 printf("\"%s%s\n", buf
, (len
== 0 ? "\"" : " ..."));
372 _sdp_data_print(const uint8_t *next
, const uint8_t *end
, int indent
)
382 _sdp_put(indent
, "nil", "");
389 _sdp_put(indent
, "bool", "%s",
390 (*next
== 0x00 ? "false" : "true"));
399 _sdp_put(indent
, "int8", "%" PRId8
,
400 *(const int8_t *)next
);
408 _sdp_put(indent
, "uint8", "0x%02" PRIx8
,
417 _sdp_put(indent
, "int16", "%" PRId16
,
418 (int16_t)be16dec(next
));
422 case SDP_DATA_UINT16
:
426 _sdp_put(indent
, "uint16", "0x%04" PRIx16
,
431 case SDP_DATA_UUID16
:
435 _sdp_put(indent
, "uuid16", "0x%04" PRIx16
,
444 _sdp_put(indent
, "int32", "%" PRId32
,
445 (int32_t)be32dec(next
));
449 case SDP_DATA_UINT32
:
453 _sdp_put(indent
, "uint32", "0x%08" PRIx32
,
458 case SDP_DATA_UUID32
:
462 _sdp_put(indent
, "uuid32", "0x%08" PRIx32
,
471 _sdp_put(indent
, "int64", "%" PRId64
,
472 (int64_t)be64dec(next
));
476 case SDP_DATA_UINT64
:
480 _sdp_put(indent
, "uint64", "0x%016" PRIx64
,
485 case SDP_DATA_INT128
:
489 _sdp_put(indent
, "int128",
490 "0x%02x%02x%02x%02x%02x%02x%02x%02x"
491 "%02x%02x%02x%02x%02x%02x%02x%02x",
492 next
[0], next
[1], next
[2], next
[3],
493 next
[4], next
[5], next
[6], next
[7],
494 next
[8], next
[9], next
[10], next
[11],
495 next
[12], next
[13], next
[14], next
[15]);
499 case SDP_DATA_UINT128
:
503 _sdp_put(indent
, "uint128",
504 "0x%02x%02x%02x%02x%02x%02x%02x%02x"
505 "%02x%02x%02x%02x%02x%02x%02x%02x",
506 next
[0], next
[1], next
[2], next
[3],
507 next
[4], next
[5], next
[6], next
[7],
508 next
[8], next
[9], next
[10], next
[11],
509 next
[12], next
[13], next
[14], next
[15]);
513 case SDP_DATA_UUID128
:
517 _sdp_put(indent
, "uuid128",
522 "%02x%02x%02x%02x%02x%02x",
523 next
[0], next
[1], next
[2], next
[3],
527 next
[10], next
[11], next
[12],
528 next
[13], next
[14], next
[15]);
539 if (next
+ len
> end
)
542 _sdp_putstr(indent
, VIS_CSTYLE
, "str8", next
, len
);
553 if (next
+ len
> end
)
556 _sdp_putstr(indent
, VIS_HTTPSTYLE
, "url8", next
, len
);
567 if (next
+ len
> end
)
570 _sdp_putstr(indent
, VIS_CSTYLE
, "str16", next
, len
);
581 if (next
+ len
> end
)
584 _sdp_putstr(indent
, VIS_HTTPSTYLE
, "url16", next
, len
);
595 if (next
+ len
> end
)
598 _sdp_putstr(indent
, VIS_CSTYLE
, "str32", next
, len
);
609 if (next
+ len
> end
)
612 _sdp_putstr(indent
, VIS_HTTPSTYLE
, "url32", next
, len
);
623 if (next
+ len
> end
)
626 printf("%*sseq8(%zu)\n", indent
, "", len
);
627 if (!_sdp_data_print(next
, next
+ len
, indent
+ 1))
640 if (next
+ len
> end
)
643 printf("%*salt8(%zu)\n", indent
, "", len
);
644 if (!_sdp_data_print(next
, next
+ len
, indent
+ 1))
657 if (next
+ len
> end
)
660 printf("%*sseq16(%zu)\n", indent
, "", len
);
661 if (!_sdp_data_print(next
, next
+ len
, indent
+ 1))
674 if (next
+ len
> end
)
677 printf("%*salt16(%zu)\n", indent
, "", len
);
678 if (!_sdp_data_print(next
, next
+ len
, indent
+ 1))
691 if (next
+ len
> end
)
694 printf("%*sseq32(%zu)\n", indent
, "", len
);
695 if (!_sdp_data_print(next
, next
+ len
, indent
+ 1))
708 if (next
+ len
> end
)
711 printf("%*salt32(%zu)\n", indent
, "", len
);
712 if (!_sdp_data_print(next
, next
+ len
, indent
+ 1))
727 sdp_data_print(const sdp_data_t
*data
, int indent
)
730 if (!_sdp_data_print(data
->next
, data
->end
, indent
))
731 printf("SDP data error\n");