xref: /netbsd/usr.sbin/sdpd/compat.c (revision 6550d01e)
1 /*	$NetBSD: compat.c,v 1.2 2010/03/07 10:58:40 plunky Exp $	*/
2 
3 /*-
4  * Copyright (c) 2009 The NetBSD Foundation, Inc.
5  * All rights reserved.
6  *
7  * This code is derived from software contributed to The NetBSD Foundation
8  * by Iain Hibbert.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
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.
18  *
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.
30  */
31 
32 #include <sys/cdefs.h>
33 __RCSID("$NetBSD: compat.c,v 1.2 2010/03/07 10:58:40 plunky Exp $");
34 
35 #include <arpa/inet.h>
36 
37 #include <netbt/rfcomm.h>
38 
39 #include <bluetooth.h>
40 #include <errno.h>
41 #include <sdp.h>
42 #include <stdlib.h>
43 #include <string.h>
44 #include <unistd.h>
45 
46 #include "sdpd.h"
47 
48 /*
49  * This file provides for compatibility with the old ABI. Clients send
50  * a data structure and we generate a record based from that using the
51  * server output buffer as temporary storage. The sdp_put functions will
52  * not write invalid data or overflow the buffer which is big enough to
53  * contain all these records, no need to worry about that.
54  */
55 
56 static bool
57 dun_profile(sdp_data_t *buf, void *arg, ssize_t len)
58 {
59 	sdp_dun_profile_t	*data = arg;
60 	uint8_t			*first = buf->next;
61 
62 	if (len != sizeof(*data)
63 	    || data->server_channel < RFCOMM_CHANNEL_MIN
64 	    || data->server_channel > RFCOMM_CHANNEL_MAX)
65 		return false;
66 
67 	sdp_put_uint16(buf, SDP_ATTR_SERVICE_RECORD_HANDLE);
68 	sdp_put_uint32(buf, 0x00000000);
69 
70 	sdp_put_uint16(buf, SDP_ATTR_SERVICE_CLASS_ID_LIST);
71 	sdp_put_seq(buf, 3);
72 	sdp_put_uuid16(buf, SDP_SERVICE_CLASS_DIALUP_NETWORKING);
73 
74 	sdp_put_uint16(buf, SDP_ATTR_PROTOCOL_DESCRIPTOR_LIST);
75 	sdp_put_seq(buf, 12);
76 	sdp_put_seq(buf, 3);
77 	sdp_put_uuid16(buf, SDP_UUID_PROTOCOL_L2CAP);
78 	sdp_put_seq(buf, 5);
79 	sdp_put_uuid16(buf, SDP_UUID_PROTOCOL_RFCOMM);
80 	sdp_put_uint8(buf, data->server_channel);
81 
82 	sdp_put_uint16(buf, SDP_ATTR_BROWSE_GROUP_LIST);
83 	sdp_put_seq(buf, 3);
84 	sdp_put_uuid16(buf, SDP_SERVICE_CLASS_PUBLIC_BROWSE_GROUP);
85 
86 	sdp_put_uint16(buf, SDP_ATTR_LANGUAGE_BASE_ATTRIBUTE_ID_LIST);
87 	sdp_put_seq(buf, 9);
88 	sdp_put_uint16(buf, 0x656e);	/* "en" */
89 	sdp_put_uint16(buf, 106);	/* UTF-8 */
90 	sdp_put_uint16(buf, SDP_ATTR_PRIMARY_LANGUAGE_BASE_ID);
91 
92 	sdp_put_uint16(buf, SDP_ATTR_BLUETOOTH_PROFILE_DESCRIPTOR_LIST);
93 	sdp_put_seq(buf, 8);
94 	sdp_put_seq(buf, 6);
95 	sdp_put_uuid16(buf, SDP_SERVICE_CLASS_DIALUP_NETWORKING);
96 	sdp_put_uint16(buf, 0x0100);	/* v1.0 */
97 
98 	sdp_put_uint16(buf, SDP_ATTR_PRIMARY_LANGUAGE_BASE_ID + SDP_ATTR_SERVICE_NAME_OFFSET);
99 	sdp_put_str(buf, "Dialup Networking", -1);
100 
101 	sdp_put_uint16(buf, SDP_ATTR_AUDIO_FEEDBACK_SUPPORT);
102 	sdp_put_bool(buf, data->audio_feedback_support);
103 
104 	buf->end = buf->next;
105 	buf->next = first;
106 	return true;
107 }
108 
109 static bool
110 ftrn_profile(sdp_data_t *buf, void *arg, ssize_t len)
111 {
112 	sdp_ftrn_profile_t	*data = arg;
113 	uint8_t			*first = buf->next;
114 
115 	if (len != sizeof(*data)
116 	    || data->server_channel < RFCOMM_CHANNEL_MIN
117 	    || data->server_channel > RFCOMM_CHANNEL_MAX)
118 		return false;
119 
120 	sdp_put_uint16(buf, SDP_ATTR_SERVICE_RECORD_HANDLE);
121 	sdp_put_uint32(buf, 0x00000000);
122 
123 	sdp_put_uint16(buf, SDP_ATTR_SERVICE_CLASS_ID_LIST);
124 	sdp_put_seq(buf, 3);
125 	sdp_put_uuid16(buf, SDP_SERVICE_CLASS_OBEX_FILE_TRANSFER);
126 
127 	sdp_put_uint16(buf, SDP_ATTR_PROTOCOL_DESCRIPTOR_LIST);
128 	sdp_put_seq(buf, 17);
129 	sdp_put_seq(buf, 3);
130 	sdp_put_uuid16(buf, SDP_UUID_PROTOCOL_L2CAP);
131 	sdp_put_seq(buf, 5);
132 	sdp_put_uuid16(buf, SDP_UUID_PROTOCOL_RFCOMM);
133 	sdp_put_uint8(buf, data->server_channel);
134 	sdp_put_seq(buf, 3);
135 	sdp_put_uuid16(buf, SDP_UUID_PROTOCOL_OBEX);
136 
137 	sdp_put_uint16(buf, SDP_ATTR_BROWSE_GROUP_LIST);
138 	sdp_put_seq(buf, 3);
139 	sdp_put_uuid16(buf, SDP_SERVICE_CLASS_PUBLIC_BROWSE_GROUP);
140 
141 	sdp_put_uint16(buf, SDP_ATTR_LANGUAGE_BASE_ATTRIBUTE_ID_LIST);
142 	sdp_put_seq(buf, 9);
143 	sdp_put_uint16(buf, 0x656e);	/* "en" */
144 	sdp_put_uint16(buf, 106);	/* UTF-8 */
145 	sdp_put_uint16(buf, SDP_ATTR_PRIMARY_LANGUAGE_BASE_ID);
146 
147 	sdp_put_uint16(buf, SDP_ATTR_BLUETOOTH_PROFILE_DESCRIPTOR_LIST);
148 	sdp_put_seq(buf, 8);
149 	sdp_put_seq(buf, 6);
150 	sdp_put_uuid16(buf, SDP_SERVICE_CLASS_OBEX_FILE_TRANSFER);
151 	sdp_put_uint16(buf, 0x0100);	/* v1.0 */
152 
153 	sdp_put_uint16(buf, SDP_ATTR_PRIMARY_LANGUAGE_BASE_ID + SDP_ATTR_SERVICE_NAME_OFFSET);
154 	sdp_put_str(buf, "OBEX File Transfer", -1);
155 
156 	buf->end = buf->next;
157 	buf->next = first;
158 	return true;
159 }
160 
161 static bool
162 hset_profile(sdp_data_t *buf, void *arg, ssize_t len)
163 {
164 	sdp_hset_profile_t	*data = arg;
165 	uint8_t			*first = buf->next;
166 
167 	if (len != sizeof(*data)
168 	    || data->server_channel < RFCOMM_CHANNEL_MIN
169 	    || data->server_channel > RFCOMM_CHANNEL_MAX)
170 		return false;
171 
172 	sdp_put_uint16(buf, SDP_ATTR_SERVICE_RECORD_HANDLE);
173 	sdp_put_uint32(buf, 0x00000000);
174 
175 	sdp_put_uint16(buf, SDP_ATTR_SERVICE_CLASS_ID_LIST);
176 	sdp_put_seq(buf, 6);
177 	sdp_put_uuid16(buf, SDP_SERVICE_CLASS_HEADSET_AUDIO_GATEWAY);
178 	sdp_put_uuid16(buf, SDP_SERVICE_CLASS_GENERIC_AUDIO);
179 
180 	sdp_put_uint16(buf, SDP_ATTR_PROTOCOL_DESCRIPTOR_LIST);
181 	sdp_put_seq(buf, 12);
182 	sdp_put_seq(buf, 3);
183 	sdp_put_uuid16(buf, SDP_UUID_PROTOCOL_L2CAP);
184 	sdp_put_seq(buf, 5);
185 	sdp_put_uuid16(buf, SDP_UUID_PROTOCOL_RFCOMM);
186 	sdp_put_uint8(buf, data->server_channel);
187 
188 	sdp_put_uint16(buf, SDP_ATTR_BROWSE_GROUP_LIST);
189 	sdp_put_seq(buf, 3);
190 	sdp_put_uuid16(buf, SDP_SERVICE_CLASS_PUBLIC_BROWSE_GROUP);
191 
192 	sdp_put_uint16(buf, SDP_ATTR_LANGUAGE_BASE_ATTRIBUTE_ID_LIST);
193 	sdp_put_seq(buf, 9);
194 	sdp_put_uint16(buf, 0x656e);	/* "en" */
195 	sdp_put_uint16(buf, 106);	/* UTF-8 */
196 	sdp_put_uint16(buf, SDP_ATTR_PRIMARY_LANGUAGE_BASE_ID);
197 
198 	sdp_put_uint16(buf, SDP_ATTR_BLUETOOTH_PROFILE_DESCRIPTOR_LIST);
199 	sdp_put_seq(buf, 8);
200 	sdp_put_seq(buf, 6);
201 	sdp_put_uuid16(buf, SDP_SERVICE_CLASS_HEADSET);
202 	sdp_put_uint16(buf, 0x0100);	/* v1.0 */
203 
204 	sdp_put_uint16(buf, SDP_ATTR_PRIMARY_LANGUAGE_BASE_ID + SDP_ATTR_SERVICE_NAME_OFFSET);
205 	sdp_put_str(buf, "Voice Gateway", -1);
206 
207 	buf->end = buf->next;
208 	buf->next = first;
209 	return true;
210 }
211 
212 static bool
213 hf_profile(sdp_data_t *buf, void *arg, ssize_t len)
214 {
215 	sdp_hf_profile_t	*data = arg;
216 	uint8_t			*first = buf->next;
217 
218 	if (len != sizeof(*data)
219 	    || data->server_channel < RFCOMM_CHANNEL_MIN
220 	    || data->server_channel > RFCOMM_CHANNEL_MAX
221 	    || (data->supported_features & ~0x001f))
222 		return false;
223 
224 	sdp_put_uint16(buf, SDP_ATTR_SERVICE_RECORD_HANDLE);
225 	sdp_put_uint32(buf, 0x00000000);
226 
227 	sdp_put_uint16(buf, SDP_ATTR_SERVICE_CLASS_ID_LIST);
228 	sdp_put_seq(buf, 6);
229 	sdp_put_uuid16(buf, SDP_SERVICE_CLASS_HANDSFREE);
230 	sdp_put_uuid16(buf, SDP_SERVICE_CLASS_GENERIC_AUDIO);
231 
232 	sdp_put_uint16(buf, SDP_ATTR_PROTOCOL_DESCRIPTOR_LIST);
233 	sdp_put_seq(buf, 12);
234 	sdp_put_seq(buf, 3);
235 	sdp_put_uuid16(buf, SDP_UUID_PROTOCOL_L2CAP);
236 	sdp_put_seq(buf, 5);
237 	sdp_put_uuid16(buf, SDP_UUID_PROTOCOL_RFCOMM);
238 	sdp_put_uint8(buf, data->server_channel);
239 
240 	sdp_put_uint16(buf, SDP_ATTR_BROWSE_GROUP_LIST);
241 	sdp_put_seq(buf, 3);
242 	sdp_put_uuid16(buf, SDP_SERVICE_CLASS_PUBLIC_BROWSE_GROUP);
243 
244 	sdp_put_uint16(buf, SDP_ATTR_LANGUAGE_BASE_ATTRIBUTE_ID_LIST);
245 	sdp_put_seq(buf, 9);
246 	sdp_put_uint16(buf, 0x656e);	/* "en" */
247 	sdp_put_uint16(buf, 106);	/* UTF-8 */
248 	sdp_put_uint16(buf, SDP_ATTR_PRIMARY_LANGUAGE_BASE_ID);
249 
250 	sdp_put_uint16(buf, SDP_ATTR_BLUETOOTH_PROFILE_DESCRIPTOR_LIST);
251 	sdp_put_seq(buf, 8);
252 	sdp_put_seq(buf, 6);
253 	sdp_put_uuid16(buf, SDP_SERVICE_CLASS_HANDSFREE);
254 	sdp_put_uint16(buf, 0x0100);	/* v1.0 */
255 
256 	sdp_put_uint16(buf, SDP_ATTR_PRIMARY_LANGUAGE_BASE_ID + SDP_ATTR_SERVICE_NAME_OFFSET);
257 	sdp_put_str(buf, "Hands-Free unit", -1);
258 
259 	sdp_put_uint16(buf, SDP_ATTR_SUPPORTED_FEATURES);
260 	sdp_put_uint16(buf, data->supported_features);
261 
262 	buf->end = buf->next;
263 	buf->next = first;
264 	return true;
265 }
266 
267 static bool
268 irmc_profile(sdp_data_t *buf, void *arg, ssize_t len)
269 {
270 	sdp_irmc_profile_t	*data = arg;
271 	uint8_t			*first = buf->next;
272 	int			i;
273 
274 	if (len != sizeof(*data)
275 	    || data->server_channel < RFCOMM_CHANNEL_MIN
276 	    || data->server_channel > RFCOMM_CHANNEL_MAX
277 	    || data->supported_formats_size == 0
278 	    || data->supported_formats_size > sizeof(data->supported_formats))
279 		return false;
280 
281 	sdp_put_uint16(buf, SDP_ATTR_SERVICE_RECORD_HANDLE);
282 	sdp_put_uint32(buf, 0x00000000);
283 
284 	sdp_put_uint16(buf, SDP_ATTR_SERVICE_CLASS_ID_LIST);
285 	sdp_put_seq(buf, 3);
286 	sdp_put_uuid16(buf, SDP_SERVICE_CLASS_IR_MC_SYNC);
287 
288 	sdp_put_uint16(buf, SDP_ATTR_PROTOCOL_DESCRIPTOR_LIST);
289 	sdp_put_seq(buf, 17);
290 	sdp_put_seq(buf, 3);
291 	sdp_put_uuid16(buf, SDP_UUID_PROTOCOL_L2CAP);
292 	sdp_put_seq(buf, 5);
293 	sdp_put_uuid16(buf, SDP_UUID_PROTOCOL_RFCOMM);
294 	sdp_put_uint8(buf, data->server_channel);
295 	sdp_put_seq(buf, 3);
296 	sdp_put_uuid16(buf, SDP_UUID_PROTOCOL_OBEX);
297 
298 	sdp_put_uint16(buf, SDP_ATTR_BROWSE_GROUP_LIST);
299 	sdp_put_seq(buf, 3);
300 	sdp_put_uuid16(buf, SDP_SERVICE_CLASS_PUBLIC_BROWSE_GROUP);
301 
302 	sdp_put_uint16(buf, SDP_ATTR_LANGUAGE_BASE_ATTRIBUTE_ID_LIST);
303 	sdp_put_seq(buf, 9);
304 	sdp_put_uint16(buf, 0x656e);	/* "en" */
305 	sdp_put_uint16(buf, 106);	/* UTF-8 */
306 	sdp_put_uint16(buf, SDP_ATTR_PRIMARY_LANGUAGE_BASE_ID);
307 
308 	sdp_put_uint16(buf, SDP_ATTR_BLUETOOTH_PROFILE_DESCRIPTOR_LIST);
309 	sdp_put_seq(buf, 8);
310 	sdp_put_seq(buf, 6);
311 	sdp_put_uuid16(buf, SDP_SERVICE_CLASS_IR_MC_SYNC);
312 	sdp_put_uint16(buf, 0x0100);	/* v1.0 */
313 
314 	sdp_put_uint16(buf, SDP_ATTR_PRIMARY_LANGUAGE_BASE_ID + SDP_ATTR_SERVICE_NAME_OFFSET);
315 	sdp_put_str(buf, "IrMC Syncrhonization", -1);
316 
317 	sdp_put_uint16(buf, SDP_ATTR_SUPPORTED_DATA_STORES_LIST);
318 	sdp_put_seq(buf, data->supported_formats_size * 2);
319 	for (i = 0; i < data->supported_formats_size; i++)
320 		sdp_put_uint8(buf, data->supported_formats[i]);
321 
322 	buf->end = buf->next;
323 	buf->next = first;
324 	return true;
325 }
326 
327 static bool
328 irmc_cmd_profile(sdp_data_t *buf, void *arg, ssize_t len)
329 {
330 	sdp_irmc_command_profile_t	*data = arg;
331 	uint8_t				*first = buf->next;
332 
333 	if (len != sizeof(*data)
334 	    || data->server_channel < RFCOMM_CHANNEL_MIN
335 	    || data->server_channel > RFCOMM_CHANNEL_MAX)
336 		return false;
337 
338 	sdp_put_uint16(buf, SDP_ATTR_SERVICE_RECORD_HANDLE);
339 	sdp_put_uint32(buf, 0x00000000);
340 
341 	sdp_put_uint16(buf, SDP_ATTR_SERVICE_CLASS_ID_LIST);
342 	sdp_put_seq(buf, 3);
343 	sdp_put_uuid16(buf, SDP_SERVICE_CLASS_IR_MC_SYNC_COMMAND);
344 
345 	sdp_put_uint16(buf, SDP_ATTR_PROTOCOL_DESCRIPTOR_LIST);
346 	sdp_put_seq(buf, 17);
347 	sdp_put_seq(buf, 3);
348 	sdp_put_uuid16(buf, SDP_UUID_PROTOCOL_L2CAP);
349 	sdp_put_seq(buf, 5);
350 	sdp_put_uuid16(buf, SDP_UUID_PROTOCOL_RFCOMM);
351 	sdp_put_uint8(buf, data->server_channel);
352 	sdp_put_seq(buf, 3);
353 	sdp_put_uuid16(buf, SDP_UUID_PROTOCOL_OBEX);
354 
355 	sdp_put_uint16(buf, SDP_ATTR_BROWSE_GROUP_LIST);
356 	sdp_put_seq(buf, 3);
357 	sdp_put_uuid16(buf, SDP_SERVICE_CLASS_PUBLIC_BROWSE_GROUP);
358 
359 	sdp_put_uint16(buf, SDP_ATTR_LANGUAGE_BASE_ATTRIBUTE_ID_LIST);
360 	sdp_put_seq(buf, 9);
361 	sdp_put_uint16(buf, 0x656e);	/* "en" */
362 	sdp_put_uint16(buf, 106);	/* UTF-8 */
363 	sdp_put_uint16(buf, SDP_ATTR_PRIMARY_LANGUAGE_BASE_ID);
364 
365 	sdp_put_uint16(buf, SDP_ATTR_BLUETOOTH_PROFILE_DESCRIPTOR_LIST);
366 	sdp_put_seq(buf, 8);
367 	sdp_put_seq(buf, 6);
368 	sdp_put_uuid16(buf, SDP_SERVICE_CLASS_IR_MC_SYNC_COMMAND);
369 	sdp_put_uint16(buf, 0x0100);	/* v1.0 */
370 
371 	sdp_put_uint16(buf, SDP_ATTR_PRIMARY_LANGUAGE_BASE_ID + SDP_ATTR_SERVICE_NAME_OFFSET);
372 	sdp_put_str(buf, "Sync Command Service", -1);
373 
374 	buf->end = buf->next;
375 	buf->next = first;
376 	return true;
377 }
378 
379 static bool
380 lan_profile(sdp_data_t *buf, void *arg, ssize_t len)
381 {
382 	sdp_lan_profile_t	*data = arg;
383 	uint8_t			*first = buf->next;
384 	struct in_addr		in;
385 	char			str[32];
386 
387 	if (len != sizeof(*data)
388 	    || data->server_channel < RFCOMM_CHANNEL_MIN
389 	    || data->server_channel > RFCOMM_CHANNEL_MAX
390 	    || data->ip_subnet_radius > 32)
391 		return false;
392 
393 	sdp_put_uint16(buf, SDP_ATTR_SERVICE_RECORD_HANDLE);
394 	sdp_put_uint32(buf, 0x00000000);
395 
396 	sdp_put_uint16(buf, SDP_ATTR_SERVICE_CLASS_ID_LIST);
397 	sdp_put_seq(buf, 3);
398 	sdp_put_uuid16(buf, SDP_SERVICE_CLASS_LAN_ACCESS_USING_PPP);
399 
400 	sdp_put_uint16(buf, SDP_ATTR_PROTOCOL_DESCRIPTOR_LIST);
401 	sdp_put_seq(buf, 12);
402 	sdp_put_seq(buf, 3);
403 	sdp_put_uuid16(buf, SDP_UUID_PROTOCOL_L2CAP);
404 	sdp_put_seq(buf, 5);
405 	sdp_put_uuid16(buf, SDP_UUID_PROTOCOL_RFCOMM);
406 	sdp_put_uint8(buf, data->server_channel);
407 
408 	sdp_put_uint16(buf, SDP_ATTR_BROWSE_GROUP_LIST);
409 	sdp_put_seq(buf, 3);
410 	sdp_put_uuid16(buf, SDP_SERVICE_CLASS_PUBLIC_BROWSE_GROUP);
411 
412 	sdp_put_uint16(buf, SDP_ATTR_LANGUAGE_BASE_ATTRIBUTE_ID_LIST);
413 	sdp_put_seq(buf, 9);
414 	sdp_put_uint16(buf, 0x656e);	/* "en" */
415 	sdp_put_uint16(buf, 106);	/* UTF-8 */
416 	sdp_put_uint16(buf, SDP_ATTR_PRIMARY_LANGUAGE_BASE_ID);
417 
418 	sdp_put_uint16(buf, SDP_ATTR_SERVICE_AVAILABILITY);
419 	sdp_put_uint8(buf, data->load_factor);
420 
421 	sdp_put_uint16(buf, SDP_ATTR_BLUETOOTH_PROFILE_DESCRIPTOR_LIST);
422 	sdp_put_seq(buf, 8);
423 	sdp_put_seq(buf, 6);
424 	sdp_put_uuid16(buf, SDP_SERVICE_CLASS_LAN_ACCESS_USING_PPP);
425 	sdp_put_uint16(buf, 0x0100);	/* v1.0 */
426 
427 	sdp_put_uint16(buf, SDP_ATTR_PRIMARY_LANGUAGE_BASE_ID + SDP_ATTR_SERVICE_NAME_OFFSET);
428 	sdp_put_str(buf, "LAN Access using PPP", -1);
429 
430 	in.s_addr= data->ip_subnet;
431 	sprintf(str, "%s/%d", inet_ntoa(in), data->ip_subnet_radius);
432 	sdp_put_uint16(buf, SDP_ATTR_IP_SUBNET);
433 	sdp_put_str(buf, str, -1);
434 
435 	buf->end = buf->next;
436 	buf->next = first;
437 	return true;
438 }
439 
440 static bool
441 opush_profile(sdp_data_t *buf, void *arg, ssize_t len)
442 {
443 	sdp_opush_profile_t	*data = arg;
444 	uint8_t			*first = buf->next;
445 	int			i;
446 
447 	if (len != sizeof(*data)
448 	    || data->server_channel < RFCOMM_CHANNEL_MIN
449 	    || data->server_channel > RFCOMM_CHANNEL_MAX
450 	    || data->supported_formats_size == 0
451 	    || data->supported_formats_size > sizeof(data->supported_formats))
452 		return false;
453 
454 	sdp_put_uint16(buf, SDP_ATTR_SERVICE_RECORD_HANDLE);
455 	sdp_put_uint32(buf, 0x00000000);
456 
457 	sdp_put_uint16(buf, SDP_ATTR_SERVICE_CLASS_ID_LIST);
458 	sdp_put_seq(buf, 3);
459 	sdp_put_uuid16(buf, SDP_SERVICE_CLASS_OBEX_OBJECT_PUSH);
460 
461 	sdp_put_uint16(buf, SDP_ATTR_PROTOCOL_DESCRIPTOR_LIST);
462 	sdp_put_seq(buf, 17);
463 	sdp_put_seq(buf, 3);
464 	sdp_put_uuid16(buf, SDP_UUID_PROTOCOL_L2CAP);
465 	sdp_put_seq(buf, 5);
466 	sdp_put_uuid16(buf, SDP_UUID_PROTOCOL_RFCOMM);
467 	sdp_put_uint8(buf, data->server_channel);
468 	sdp_put_seq(buf, 3);
469 	sdp_put_uuid16(buf, SDP_UUID_PROTOCOL_OBEX);
470 
471 	sdp_put_uint16(buf, SDP_ATTR_BROWSE_GROUP_LIST);
472 	sdp_put_seq(buf, 3);
473 	sdp_put_uuid16(buf, SDP_SERVICE_CLASS_PUBLIC_BROWSE_GROUP);
474 
475 	sdp_put_uint16(buf, SDP_ATTR_LANGUAGE_BASE_ATTRIBUTE_ID_LIST);
476 	sdp_put_seq(buf, 9);
477 	sdp_put_uint16(buf, 0x656e);	/* "en" */
478 	sdp_put_uint16(buf, 106);	/* UTF-8 */
479 	sdp_put_uint16(buf, SDP_ATTR_PRIMARY_LANGUAGE_BASE_ID);
480 
481 	sdp_put_uint16(buf, SDP_ATTR_BLUETOOTH_PROFILE_DESCRIPTOR_LIST);
482 	sdp_put_seq(buf, 8);
483 	sdp_put_seq(buf, 6);
484 	sdp_put_uuid16(buf, SDP_SERVICE_CLASS_OBEX_OBJECT_PUSH);
485 	sdp_put_uint16(buf, 0x0100);	/* v1.0 */
486 
487 	sdp_put_uint16(buf, SDP_ATTR_PRIMARY_LANGUAGE_BASE_ID + SDP_ATTR_SERVICE_NAME_OFFSET);
488 	sdp_put_str(buf, "OBEX Object Push", -1);
489 
490 	sdp_put_uint16(buf, SDP_ATTR_SUPPORTED_FORMATS_LIST);
491 	sdp_put_seq(buf, data->supported_formats_size * 2);
492 	for (i = 0; i < data->supported_formats_size; i++)
493 		sdp_put_uint8(buf, data->supported_formats[i]);
494 
495 	buf->end = buf->next;
496 	buf->next = first;
497 	return true;
498 }
499 
500 static bool
501 sp_profile(sdp_data_t *buf, void *arg, ssize_t len)
502 {
503 	sdp_sp_profile_t	*data = arg;
504 	uint8_t			*first = buf->next;
505 
506 	if (len != sizeof(*data)
507 	    || data->server_channel < RFCOMM_CHANNEL_MIN
508 	    || data->server_channel > RFCOMM_CHANNEL_MAX)
509 		return false;
510 
511 	sdp_put_uint16(buf, SDP_ATTR_SERVICE_RECORD_HANDLE);
512 	sdp_put_uint32(buf, 0x00000000);
513 
514 	sdp_put_uint16(buf, SDP_ATTR_SERVICE_CLASS_ID_LIST);
515 	sdp_put_seq(buf, 3);
516 	sdp_put_uuid16(buf, SDP_SERVICE_CLASS_SERIAL_PORT);
517 
518 	sdp_put_uint16(buf, SDP_ATTR_PROTOCOL_DESCRIPTOR_LIST);
519 	sdp_put_seq(buf, 12);
520 	sdp_put_seq(buf, 3);
521 	sdp_put_uuid16(buf, SDP_UUID_PROTOCOL_L2CAP);
522 	sdp_put_seq(buf, 5);
523 	sdp_put_uuid16(buf, SDP_UUID_PROTOCOL_RFCOMM);
524 	sdp_put_uint8(buf, data->server_channel);
525 
526 	sdp_put_uint16(buf, SDP_ATTR_BROWSE_GROUP_LIST);
527 	sdp_put_seq(buf, 3);
528 	sdp_put_uuid16(buf, SDP_SERVICE_CLASS_PUBLIC_BROWSE_GROUP);
529 
530 	sdp_put_uint16(buf, SDP_ATTR_LANGUAGE_BASE_ATTRIBUTE_ID_LIST);
531 	sdp_put_seq(buf, 9);
532 	sdp_put_uint16(buf, 0x656e);	/* "en" */
533 	sdp_put_uint16(buf, 106);	/* UTF-8 */
534 	sdp_put_uint16(buf, SDP_ATTR_PRIMARY_LANGUAGE_BASE_ID);
535 
536 	sdp_put_uint16(buf, SDP_ATTR_BLUETOOTH_PROFILE_DESCRIPTOR_LIST);
537 	sdp_put_seq(buf, 8);
538 	sdp_put_seq(buf, 6);
539 	sdp_put_uuid16(buf, SDP_SERVICE_CLASS_SERIAL_PORT);
540 	sdp_put_uint16(buf, 0x0100);	/* v1.0 */
541 
542 	sdp_put_uint16(buf, SDP_ATTR_PRIMARY_LANGUAGE_BASE_ID + SDP_ATTR_SERVICE_NAME_OFFSET);
543 	sdp_put_str(buf, "Serial Port", -1);
544 
545 	buf->end = buf->next;
546 	buf->next = first;
547 	return true;
548 }
549 
550 /* list of protocols used by PAN profiles.  */
551 static const uint16_t proto[] = {
552 	0x0800,	/* IPv4 */
553 	0x0806,	/* ARP  */
554 #ifdef INET6
555 	0x86dd,	/* IPv6 */
556 #endif
557 };
558 
559 static bool
560 nap_profile(sdp_data_t *buf, void *arg, ssize_t len)
561 {
562 	sdp_nap_profile_t	*data = arg;
563 	uint8_t			*first = buf->next;
564 	size_t			i;
565 
566 	if (len != sizeof(*data)
567 	    || L2CAP_PSM_INVALID(data->psm)
568 	    || data->security_description > 0x0002)
569 		return false;
570 
571 	sdp_put_uint16(buf, SDP_ATTR_SERVICE_RECORD_HANDLE);
572 	sdp_put_uint32(buf, 0x00000000);
573 
574 	sdp_put_uint16(buf, SDP_ATTR_SERVICE_CLASS_ID_LIST);
575 	sdp_put_seq(buf, 3);
576 	sdp_put_uuid16(buf, SDP_SERVICE_CLASS_NAP);
577 
578 	sdp_put_uint16(buf, SDP_ATTR_PROTOCOL_DESCRIPTOR_LIST);
579 	sdp_put_seq(buf, 18 + 3 * __arraycount(proto));
580 	sdp_put_seq(buf, 6);
581 	sdp_put_uuid16(buf, SDP_UUID_PROTOCOL_L2CAP);
582 	sdp_put_uint16(buf, data->psm);
583 	sdp_put_seq(buf, 8 + 3 * __arraycount(proto));
584 	sdp_put_uuid16(buf, SDP_UUID_PROTOCOL_BNEP);
585 	sdp_put_uint16(buf, 0x0100);	/* v1.0 */
586 	sdp_put_seq(buf, 3 * __arraycount(proto));
587 	for (i = 0; i < __arraycount(proto); i++)
588 		sdp_put_uint16(buf, proto[i]);
589 
590 	sdp_put_uint16(buf, SDP_ATTR_BROWSE_GROUP_LIST);
591 	sdp_put_seq(buf, 3);
592 	sdp_put_uuid16(buf, SDP_SERVICE_CLASS_PUBLIC_BROWSE_GROUP);
593 
594 	sdp_put_uint16(buf, SDP_ATTR_LANGUAGE_BASE_ATTRIBUTE_ID_LIST);
595 	sdp_put_seq(buf, 9);
596 	sdp_put_uint16(buf, 0x656e);	/* "en" */
597 	sdp_put_uint16(buf, 106);	/* UTF-8 */
598 	sdp_put_uint16(buf, SDP_ATTR_PRIMARY_LANGUAGE_BASE_ID);
599 
600 	sdp_put_uint16(buf, SDP_ATTR_SERVICE_AVAILABILITY);
601 	sdp_put_uint8(buf, data->load_factor);
602 
603 	sdp_put_uint16(buf, SDP_ATTR_BLUETOOTH_PROFILE_DESCRIPTOR_LIST);
604 	sdp_put_seq(buf, 8);
605 	sdp_put_seq(buf, 6);
606 	sdp_put_uuid16(buf, SDP_SERVICE_CLASS_NAP);
607 	sdp_put_uint16(buf, 0x0100);	/* v1.0 */
608 
609 	sdp_put_uint16(buf, SDP_ATTR_PRIMARY_LANGUAGE_BASE_ID + SDP_ATTR_SERVICE_NAME_OFFSET);
610 	sdp_put_str(buf, "Network Access Point", -1);
611 
612 	sdp_put_uint16(buf, SDP_ATTR_PRIMARY_LANGUAGE_BASE_ID + SDP_ATTR_SERVICE_DESCRIPTION_OFFSET);
613 	sdp_put_str(buf, "Personal Ad-hoc Network Service", -1);
614 
615 	sdp_put_uint16(buf, SDP_ATTR_SECURITY_DESCRIPTION);
616 	sdp_put_uint16(buf, data->security_description);
617 
618 	sdp_put_uint16(buf, SDP_ATTR_NET_ACCESS_TYPE);
619 	sdp_put_uint16(buf, data->net_access_type);
620 
621 	sdp_put_uint16(buf, SDP_ATTR_MAX_NET_ACCESS_RATE);
622 	sdp_put_uint32(buf, data->max_net_access_rate);
623 
624 	buf->end = buf->next;
625 	buf->next = first;
626 	return true;
627 }
628 
629 static bool
630 gn_profile(sdp_data_t *buf, void *arg, ssize_t len)
631 {
632 	sdp_gn_profile_t	*data = arg;
633 	uint8_t			*first = buf->next;
634 	size_t			i;
635 
636 	if (len != sizeof(*data)
637 	    || L2CAP_PSM_INVALID(data->psm)
638 	    || data->security_description > 0x0002)
639 		return false;
640 
641 	sdp_put_uint16(buf, SDP_ATTR_SERVICE_RECORD_HANDLE);
642 	sdp_put_uint32(buf, 0x00000000);
643 
644 	sdp_put_uint16(buf, SDP_ATTR_SERVICE_CLASS_ID_LIST);
645 	sdp_put_seq(buf, 3);
646 	sdp_put_uuid16(buf, SDP_SERVICE_CLASS_GN);
647 
648 	sdp_put_uint16(buf, SDP_ATTR_PROTOCOL_DESCRIPTOR_LIST);
649 	sdp_put_seq(buf, 18 + 3 * __arraycount(proto));
650 	sdp_put_seq(buf, 6);
651 	sdp_put_uuid16(buf, SDP_UUID_PROTOCOL_L2CAP);
652 	sdp_put_uint16(buf, data->psm);
653 	sdp_put_seq(buf, 8 + 3 * __arraycount(proto));
654 	sdp_put_uuid16(buf, SDP_UUID_PROTOCOL_BNEP);
655 	sdp_put_uint16(buf, 0x0100);	/* v1.0 */
656 	sdp_put_seq(buf, 3 * __arraycount(proto));
657 	for (i = 0; i < __arraycount(proto); i++)
658 		sdp_put_uint16(buf, proto[i]);
659 
660 	sdp_put_uint16(buf, SDP_ATTR_BROWSE_GROUP_LIST);
661 	sdp_put_seq(buf, 3);
662 	sdp_put_uuid16(buf, SDP_SERVICE_CLASS_PUBLIC_BROWSE_GROUP);
663 
664 	sdp_put_uint16(buf, SDP_ATTR_LANGUAGE_BASE_ATTRIBUTE_ID_LIST);
665 	sdp_put_seq(buf, 9);
666 	sdp_put_uint16(buf, 0x656e);	/* "en" */
667 	sdp_put_uint16(buf, 106);	/* UTF-8 */
668 	sdp_put_uint16(buf, SDP_ATTR_PRIMARY_LANGUAGE_BASE_ID);
669 
670 	sdp_put_uint16(buf, SDP_ATTR_SERVICE_AVAILABILITY);
671 	sdp_put_uint8(buf, data->load_factor);
672 
673 	sdp_put_uint16(buf, SDP_ATTR_BLUETOOTH_PROFILE_DESCRIPTOR_LIST);
674 	sdp_put_seq(buf, 8);
675 	sdp_put_seq(buf, 6);
676 	sdp_put_uuid16(buf, SDP_SERVICE_CLASS_GN);
677 	sdp_put_uint16(buf, 0x0100);	/* v1.0 */
678 
679 	sdp_put_uint16(buf, SDP_ATTR_PRIMARY_LANGUAGE_BASE_ID + SDP_ATTR_SERVICE_NAME_OFFSET);
680 	sdp_put_str(buf, "Group Ad-hoc Network", -1);
681 
682 	sdp_put_uint16(buf, SDP_ATTR_PRIMARY_LANGUAGE_BASE_ID + SDP_ATTR_SERVICE_DESCRIPTION_OFFSET);
683 	sdp_put_str(buf, "Personal Group Ad-hoc Network Service", -1);
684 
685 	sdp_put_uint16(buf, SDP_ATTR_SECURITY_DESCRIPTION);
686 	sdp_put_uint16(buf, data->security_description);
687 
688 	buf->end = buf->next;
689 	buf->next = first;
690 	return true;
691 }
692 
693 static bool
694 panu_profile(sdp_data_t *buf, void *arg, ssize_t len)
695 {
696 	sdp_panu_profile_t	*data = arg;
697 	uint8_t			*first = buf->next;
698 	size_t			i;
699 
700 	if (len != sizeof(*data)
701 	    || L2CAP_PSM_INVALID(data->psm)
702 	    || data->security_description > 0x0002)
703 		return false;
704 
705 	sdp_put_uint16(buf, SDP_ATTR_SERVICE_RECORD_HANDLE);
706 	sdp_put_uint32(buf, 0x00000000);
707 
708 	sdp_put_uint16(buf, SDP_ATTR_SERVICE_CLASS_ID_LIST);
709 	sdp_put_seq(buf, 3);
710 	sdp_put_uuid16(buf, SDP_SERVICE_CLASS_PANU);
711 
712 	sdp_put_uint16(buf, SDP_ATTR_PROTOCOL_DESCRIPTOR_LIST);
713 	sdp_put_seq(buf, 18 + 3 * __arraycount(proto));
714 	sdp_put_seq(buf, 6);
715 	sdp_put_uuid16(buf, SDP_UUID_PROTOCOL_L2CAP);
716 	sdp_put_uint16(buf, data->psm);
717 	sdp_put_seq(buf, 8 + 3 * __arraycount(proto));
718 	sdp_put_uuid16(buf, SDP_UUID_PROTOCOL_BNEP);
719 	sdp_put_uint16(buf, 0x0100);	/* v1.0 */
720 	sdp_put_seq(buf, 3 * __arraycount(proto));
721 	for (i = 0; i < __arraycount(proto); i++)
722 		sdp_put_uint16(buf, proto[i]);
723 
724 	sdp_put_uint16(buf, SDP_ATTR_BROWSE_GROUP_LIST);
725 	sdp_put_seq(buf, 3);
726 	sdp_put_uuid16(buf, SDP_SERVICE_CLASS_PUBLIC_BROWSE_GROUP);
727 
728 	sdp_put_uint16(buf, SDP_ATTR_LANGUAGE_BASE_ATTRIBUTE_ID_LIST);
729 	sdp_put_seq(buf, 9);
730 	sdp_put_uint16(buf, 0x656e);	/* "en" */
731 	sdp_put_uint16(buf, 106);	/* UTF-8 */
732 	sdp_put_uint16(buf, SDP_ATTR_PRIMARY_LANGUAGE_BASE_ID);
733 
734 	sdp_put_uint16(buf, SDP_ATTR_SERVICE_AVAILABILITY);
735 	sdp_put_uint8(buf, data->load_factor);
736 
737 	sdp_put_uint16(buf, SDP_ATTR_BLUETOOTH_PROFILE_DESCRIPTOR_LIST);
738 	sdp_put_seq(buf, 8);
739 	sdp_put_seq(buf, 6);
740 	sdp_put_uuid16(buf, SDP_SERVICE_CLASS_PANU);
741 	sdp_put_uint16(buf, 0x0100);	/* v1.0 */
742 
743 	sdp_put_uint16(buf, SDP_ATTR_PRIMARY_LANGUAGE_BASE_ID + SDP_ATTR_SERVICE_NAME_OFFSET);
744 	sdp_put_str(buf, "Personal Ad-hoc User Service", -1);
745 
746 	sdp_put_uint16(buf, SDP_ATTR_PRIMARY_LANGUAGE_BASE_ID + SDP_ATTR_SERVICE_DESCRIPTION_OFFSET);
747 	sdp_put_str(buf, "Personal Ad-hoc User Service", -1);
748 
749 	sdp_put_uint16(buf, SDP_ATTR_SECURITY_DESCRIPTION);
750 	sdp_put_uint16(buf, data->security_description);
751 
752 	buf->end = buf->next;
753 	buf->next = first;
754 	return true;
755 }
756 
757 static const struct {
758 	uint16_t	class;
759 	bool		(*create)(sdp_data_t *, void *, ssize_t);
760 } known[] = {
761 	{ SDP_SERVICE_CLASS_DIALUP_NETWORKING,		dun_profile	    },
762 	{ SDP_SERVICE_CLASS_OBEX_FILE_TRANSFER,		ftrn_profile	    },
763 	{ SDP_SERVICE_CLASS_HEADSET_AUDIO_GATEWAY,	hset_profile	    },
764 	{ SDP_SERVICE_CLASS_HANDSFREE,			hf_profile	    },
765 	{ SDP_SERVICE_CLASS_IR_MC_SYNC,			irmc_profile	    },
766 	{ SDP_SERVICE_CLASS_IR_MC_SYNC_COMMAND,		irmc_cmd_profile    },
767 	{ SDP_SERVICE_CLASS_LAN_ACCESS_USING_PPP,	lan_profile	    },
768 	{ SDP_SERVICE_CLASS_OBEX_OBJECT_PUSH,		opush_profile	    },
769 	{ SDP_SERVICE_CLASS_SERIAL_PORT,		sp_profile	    },
770 	{ SDP_SERVICE_CLASS_NAP,			nap_profile	    },
771 	{ SDP_SERVICE_CLASS_GN,				gn_profile	    },
772 	{ SDP_SERVICE_CLASS_PANU,			panu_profile	    },
773 };
774 
775 uint16_t
776 compat_register_request(server_t *srv, int fd)
777 {
778 	sdp_data_t d, r;
779 	bdaddr_t bdaddr;
780 	uint16_t class;
781 	int i;
782 
783 	log_debug("compat RegisterRequest by client on fd#%d", fd);
784 
785 	if (!srv->fdidx[fd].control
786 	    || !srv->fdidx[fd].priv)
787 		return SDP_ERROR_CODE_INVALID_REQUEST_SYNTAX;
788 
789 	srv->fdidx[fd].offset = 0;
790 	db_unselect(srv, fd);
791 	d.next = srv->ibuf;
792 	d.end = srv->ibuf + srv->pdu.len;
793 
794 	if (d.next + sizeof(uint16_t) + sizeof(bdaddr_t) > d.end)
795 		return SDP_ERROR_CODE_INVALID_REQUEST_SYNTAX;
796 
797 	class = be16dec(d.next);
798 	d.next += sizeof(uint16_t);
799 
800 	memcpy(&bdaddr, d.next, sizeof(bdaddr_t));
801 	d.next += sizeof(bdaddr_t);
802 
803 	for (i = 0;; i++) {
804 		if (i == __arraycount(known))
805 			return SDP_ERROR_CODE_INVALID_REQUEST_SYNTAX;
806 
807 		if (known[i].class == class)
808 			break;
809 	}
810 
811 	r.next = srv->obuf;
812 	r.end = srv->obuf + srv->omtu;
813 	if (!(known[i].create(&r, d.next, d.end - d.next)))
814 		return SDP_ERROR_CODE_INVALID_REQUEST_SYNTAX;
815 
816 	if (!db_create(srv, fd, &bdaddr, srv->handle, &r))
817 		return SDP_ERROR_CODE_INSUFFICIENT_RESOURCES;
818 
819 	/* successful return */
820 	be16enc(srv->obuf, 0x0000);
821 	be32enc(srv->obuf + sizeof(uint16_t), srv->handle++);
822 	srv->pdu.pid = SDP_PDU_ERROR_RESPONSE;
823 	srv->pdu.len = sizeof(uint16_t) + sizeof(uint32_t);
824 	return 0;
825 }
826 
827 uint16_t
828 compat_change_request(server_t *srv, int fd)
829 {
830 	record_t *rec;
831 	sdp_data_t d, r;
832 	int i;
833 
834 	log_debug("compat ChangeRequest by client on fd#%d", fd);
835 
836 	if (!srv->fdidx[fd].control
837 	    || !srv->fdidx[fd].priv)
838 		return SDP_ERROR_CODE_INVALID_REQUEST_SYNTAX;
839 
840 	srv->fdidx[fd].offset = 0;
841 	db_unselect(srv, fd);
842 	d.next = srv->ibuf;
843 	d.end = srv->ibuf + srv->pdu.len;
844 
845 	if (d.next + sizeof(uint32_t) > d.end)
846 		return SDP_ERROR_CODE_INVALID_REQUEST_SYNTAX;
847 
848 	db_select_handle(srv, fd, be32dec(d.next));
849 	d.next += sizeof(uint32_t);
850 
851 	rec = NULL;
852 	db_next(srv, fd, &rec);
853 	if (rec == NULL || rec->fd != fd)
854 		return SDP_ERROR_CODE_INVALID_REQUEST_SYNTAX;
855 
856 	/*
857 	 * This is rather simplistic but it works. We don't keep a
858 	 * record of the ServiceClass but we do know the format of
859 	 * of the stored record and where it should be. If we dont
860 	 * find it there, just give up.
861 	 */
862 	r = rec->data;
863 	r.next += 3;		/* uint16 ServiceRecordHandle	*/
864 	r.next += 5;		/* uint32 %handle%		*/
865 	r.next += 3;		/* uint16 ServiceClassIDList	*/
866 	r.next += 2;		/* seq8				*/
867 	for (i = 0;; i++) {
868 		if (i == __arraycount(known))
869 			return SDP_ERROR_CODE_INVALID_REQUEST_SYNTAX;
870 
871 		if (sdp_match_uuid16(&r, known[i].class))
872 			break;
873 	}
874 
875 	r.next = srv->obuf;
876 	r.end = srv->obuf + srv->omtu;
877 	if (!(known[i].create(&r, d.next, d.end - d.next)))
878 		return SDP_ERROR_CODE_INVALID_REQUEST_SYNTAX;
879 
880 	if (!db_create(srv, fd, &rec->bdaddr, rec->handle, &r))
881 		return SDP_ERROR_CODE_INSUFFICIENT_RESOURCES;
882 
883 	db_unselect(srv, fd);
884 
885 	/* successful return */
886 	be16enc(srv->obuf, 0x0000);
887 	srv->pdu.pid = SDP_PDU_ERROR_RESPONSE;
888 	srv->pdu.len = sizeof(uint16_t);
889 	return 0;
890 }
891