]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - usr.sbin/bluetooth/btpand/sdp.c
Import libxo-0.7.2; add xo_options.7.
[FreeBSD/FreeBSD.git] / usr.sbin / bluetooth / btpand / sdp.c
1 /*      $NetBSD: sdp.c,v 1.2 2008/12/06 20:01:14 plunky Exp $   */
2
3 /*-
4  * Copyright (c) 2008 Iain Hibbert
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  */
27
28 /* $FreeBSD$ */
29
30 #include <sys/cdefs.h>
31 __RCSID("$NetBSD: sdp.c,v 1.2 2008/12/06 20:01:14 plunky Exp $");
32
33 #include <string.h>
34
35 #define L2CAP_SOCKET_CHECKED
36 #include "sdp.h"
37
38 /*
39  * SDP data stream manipulation routines
40  */
41
42 /* Bluetooth Base UUID */
43 static const uuid_t BASE_UUID = {
44         0x00000000,
45         0x0000,
46         0x1000,
47         0x80,
48         0x00,
49         { 0x00, 0x80, 0x5f, 0x9b, 0x34, 0xfb }
50 };
51
52 /*
53  * _sdp_match_uuid16(ptr, limit, uuid)
54  *
55  *      examine SDP data stream at ptr for a UUID, and return
56  *      true if it matches the supplied short alias bluetooth UUID.
57  *      limit is the first address past the end of valid data.
58  */
59 bool
60 _sdp_match_uuid16(uint8_t **ptr, uint8_t *limit, uint16_t uuid)
61 {
62         uint8_t *p = *ptr;
63         uuid_t u1, u2;
64
65         memcpy(&u1, &BASE_UUID, sizeof(uuid_t));
66         u1.time_low = uuid;
67
68         if (!_sdp_get_uuid(&p, limit, &u2)
69             || !uuid_equal(&u1, &u2, NULL))
70                 return false;
71
72         *ptr = p;
73         return true;
74 }
75
76 /*
77  * _sdp_get_uuid(ptr, limit, uuid)
78  *
79  *      examine SDP data stream at ptr for a UUID, and extract
80  *      to given storage, advancing ptr.
81  *      limit is the first address past the end of valid data.
82  */
83 bool
84 _sdp_get_uuid(uint8_t **ptr, uint8_t *limit, uuid_t *uuid)
85 {
86         uint8_t *p = *ptr;
87
88         if (p + 1 > limit)
89                 return false;
90
91         switch (*p++) {
92         case SDP_DATA_UUID16:
93                 if (p + 2 > limit)
94                         return false;
95
96                 memcpy(uuid, &BASE_UUID, sizeof(uuid_t));
97                 uuid->time_low = be16dec(p);
98                 p += 2;
99                 break;
100
101         case SDP_DATA_UUID32:
102                 if (p + 4 > limit)
103                         return false;
104
105                 memcpy(uuid, &BASE_UUID, sizeof(uuid_t));
106                 uuid->time_low = be32dec(p);
107                 p += 4;
108                 break;
109
110         case SDP_DATA_UUID128:
111                 if (p + 16 > limit)
112                         return false;
113
114                 uuid_dec_be(p, uuid);
115                 p += 16;
116                 break;
117
118         default:
119                 return false;
120         }
121
122         *ptr = p;
123         return true;
124 }
125
126 /*
127  * _sdp_get_seq(ptr, limit, seq)
128  *
129  *      examine SDP data stream at ptr for a sequence. return
130  *      seq pointer if found and advance ptr to next object.
131  *      limit is the first address past the end of valid data.
132  */
133 bool
134 _sdp_get_seq(uint8_t **ptr, uint8_t *limit, uint8_t **seq)
135 {
136         uint8_t *p = *ptr;
137         int32_t l;
138
139         if (p + 1 > limit)
140                 return false;
141
142         switch (*p++) {
143         case SDP_DATA_SEQ8:
144                 if (p + 1 > limit)
145                         return false;
146
147                 l = *p;
148                 p += 1;
149                 break;
150
151         case SDP_DATA_SEQ16:
152                 if (p + 2 > limit)
153                         return false;
154
155                 l = be16dec(p);
156                 p += 2;
157                 break;
158
159         case SDP_DATA_SEQ32:
160                 if (p + 4 > limit)
161                         return false;
162
163                 l = be32dec(p);
164                 p += 4;
165                 break;
166
167         default:
168                 return false;
169         }
170         if (p + l > limit)
171                 return false;
172
173         *seq = p;
174         *ptr = p + l;
175         return true;
176 }
177
178 /*
179  * _sdp_get_uint16(ptr, limit, value)
180  *
181  *      examine SDP data stream at ptr for a uint16_t, and
182  *      extract to given storage, advancing ptr.
183  *      limit is the first address past the end of valid data.
184  */
185 bool
186 _sdp_get_uint16(uint8_t **ptr, uint8_t *limit, uint16_t *value)
187 {
188         uint8_t *p = *ptr;
189         uint16_t v;
190
191         if (p + 1 > limit)
192                 return false;
193
194         switch (*p++) {
195         case SDP_DATA_UINT16:
196                 if (p + 2 > limit)
197                         return false;
198
199                 v = be16dec(p);
200                 p += 2;
201                 break;
202
203         default:
204                 return false;
205         }
206
207         *value = v;
208         *ptr = p;
209         return true;
210 }