xref: /freebsd-src/usr.sbin/bluetooth/sdpd/lan.c (revision 42b388439bd3795e09258c57a74ce9eec3651c7b)
11de7b4b8SPedro F. Giffuni /*-
207be7a6cSMaksim Yevmenkin  * lan.c
307be7a6cSMaksim Yevmenkin  *
4*4d846d26SWarner Losh  * SPDX-License-Identifier: BSD-2-Clause
51de7b4b8SPedro F. Giffuni  *
607be7a6cSMaksim Yevmenkin  * Copyright (c) 2004 Maksim Yevmenkin <m_evmenkin@yahoo.com>
707be7a6cSMaksim Yevmenkin  * All rights reserved.
807be7a6cSMaksim Yevmenkin  *
907be7a6cSMaksim Yevmenkin  * Redistribution and use in source and binary forms, with or without
1007be7a6cSMaksim Yevmenkin  * modification, are permitted provided that the following conditions
1107be7a6cSMaksim Yevmenkin  * are met:
1207be7a6cSMaksim Yevmenkin  * 1. Redistributions of source code must retain the above copyright
1307be7a6cSMaksim Yevmenkin  *    notice, this list of conditions and the following disclaimer.
1407be7a6cSMaksim Yevmenkin  * 2. Redistributions in binary form must reproduce the above copyright
1507be7a6cSMaksim Yevmenkin  *    notice, this list of conditions and the following disclaimer in the
1607be7a6cSMaksim Yevmenkin  *    documentation and/or other materials provided with the distribution.
1707be7a6cSMaksim Yevmenkin  *
1807be7a6cSMaksim Yevmenkin  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1907be7a6cSMaksim Yevmenkin  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2007be7a6cSMaksim Yevmenkin  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2107be7a6cSMaksim Yevmenkin  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
2207be7a6cSMaksim Yevmenkin  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2307be7a6cSMaksim Yevmenkin  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2407be7a6cSMaksim Yevmenkin  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2507be7a6cSMaksim Yevmenkin  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2607be7a6cSMaksim Yevmenkin  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2707be7a6cSMaksim Yevmenkin  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2807be7a6cSMaksim Yevmenkin  * SUCH DAMAGE.
2907be7a6cSMaksim Yevmenkin  *
3007be7a6cSMaksim Yevmenkin  * $Id: lan.c,v 1.5 2004/01/13 01:54:39 max Exp $
3107be7a6cSMaksim Yevmenkin  */
3207be7a6cSMaksim Yevmenkin 
3307be7a6cSMaksim Yevmenkin #include <arpa/inet.h>
3407be7a6cSMaksim Yevmenkin #include <sys/queue.h>
358d6f425dSTakanori Watanabe #define L2CAP_SOCKET_CHECKED
3607be7a6cSMaksim Yevmenkin #include <bluetooth.h>
3707be7a6cSMaksim Yevmenkin #include <sdp.h>
3807be7a6cSMaksim Yevmenkin #include <stdio.h>
3907be7a6cSMaksim Yevmenkin #include <string.h>
4007be7a6cSMaksim Yevmenkin #include "profile.h"
4107be7a6cSMaksim Yevmenkin #include "provider.h"
4207be7a6cSMaksim Yevmenkin 
4307be7a6cSMaksim Yevmenkin static int32_t
lan_profile_create_service_class_id_list(uint8_t * buf,uint8_t const * const eob,uint8_t const * data,uint32_t datalen)4407be7a6cSMaksim Yevmenkin lan_profile_create_service_class_id_list(
4507be7a6cSMaksim Yevmenkin 		uint8_t *buf, uint8_t const * const eob,
4607be7a6cSMaksim Yevmenkin 		uint8_t const *data, uint32_t datalen)
4707be7a6cSMaksim Yevmenkin {
4807be7a6cSMaksim Yevmenkin 	static uint16_t	service_classes[] = {
4907be7a6cSMaksim Yevmenkin 		SDP_SERVICE_CLASS_LAN_ACCESS_USING_PPP
5007be7a6cSMaksim Yevmenkin 	};
5107be7a6cSMaksim Yevmenkin 
5207be7a6cSMaksim Yevmenkin 	return (common_profile_create_service_class_id_list(
5307be7a6cSMaksim Yevmenkin 			buf, eob,
5407be7a6cSMaksim Yevmenkin 			(uint8_t const *) service_classes,
5507be7a6cSMaksim Yevmenkin 			sizeof(service_classes)));
5607be7a6cSMaksim Yevmenkin }
5707be7a6cSMaksim Yevmenkin 
5807be7a6cSMaksim Yevmenkin static int32_t
lan_profile_create_bluetooth_profile_descriptor_list(uint8_t * buf,uint8_t const * const eob,uint8_t const * data,uint32_t datalen)5907be7a6cSMaksim Yevmenkin lan_profile_create_bluetooth_profile_descriptor_list(
6007be7a6cSMaksim Yevmenkin 		uint8_t *buf, uint8_t const * const eob,
6107be7a6cSMaksim Yevmenkin 		uint8_t const *data, uint32_t datalen)
6207be7a6cSMaksim Yevmenkin {
6307be7a6cSMaksim Yevmenkin 	static uint16_t	profile_descriptor_list[] = {
6407be7a6cSMaksim Yevmenkin 		SDP_SERVICE_CLASS_LAN_ACCESS_USING_PPP,
6507be7a6cSMaksim Yevmenkin 		0x0100
6607be7a6cSMaksim Yevmenkin 	};
6707be7a6cSMaksim Yevmenkin 
6807be7a6cSMaksim Yevmenkin 	return (common_profile_create_bluetooth_profile_descriptor_list(
6907be7a6cSMaksim Yevmenkin 			buf, eob,
7007be7a6cSMaksim Yevmenkin 			(uint8_t const *) profile_descriptor_list,
7107be7a6cSMaksim Yevmenkin 			sizeof(profile_descriptor_list)));
7207be7a6cSMaksim Yevmenkin }
7307be7a6cSMaksim Yevmenkin 
7407be7a6cSMaksim Yevmenkin static int32_t
lan_profile_create_service_name(uint8_t * buf,uint8_t const * const eob,uint8_t const * data,uint32_t datalen)7507be7a6cSMaksim Yevmenkin lan_profile_create_service_name(
7607be7a6cSMaksim Yevmenkin 		uint8_t *buf, uint8_t const * const eob,
7707be7a6cSMaksim Yevmenkin 		uint8_t const *data, uint32_t datalen)
7807be7a6cSMaksim Yevmenkin {
7907be7a6cSMaksim Yevmenkin 	static char	service_name[] = "LAN Access using PPP";
8007be7a6cSMaksim Yevmenkin 
8107be7a6cSMaksim Yevmenkin 	return (common_profile_create_string8(
8207be7a6cSMaksim Yevmenkin 			buf, eob,
8307be7a6cSMaksim Yevmenkin 			(uint8_t const *) service_name, strlen(service_name)));
8407be7a6cSMaksim Yevmenkin }
8507be7a6cSMaksim Yevmenkin 
8607be7a6cSMaksim Yevmenkin static int32_t
lan_profile_create_protocol_descriptor_list(uint8_t * buf,uint8_t const * const eob,uint8_t const * data,uint32_t datalen)8707be7a6cSMaksim Yevmenkin lan_profile_create_protocol_descriptor_list(
8807be7a6cSMaksim Yevmenkin 		uint8_t *buf, uint8_t const * const eob,
8907be7a6cSMaksim Yevmenkin 		uint8_t const *data, uint32_t datalen)
9007be7a6cSMaksim Yevmenkin {
9107be7a6cSMaksim Yevmenkin 	provider_p		provider = (provider_p) data;
9207be7a6cSMaksim Yevmenkin 	sdp_lan_profile_p	lan = (sdp_lan_profile_p) provider->data;
9307be7a6cSMaksim Yevmenkin 
9407be7a6cSMaksim Yevmenkin 	return (rfcomm_profile_create_protocol_descriptor_list(
9507be7a6cSMaksim Yevmenkin 			buf, eob,
9607be7a6cSMaksim Yevmenkin 			(uint8_t const *) &lan->server_channel, 1));
9707be7a6cSMaksim Yevmenkin }
9807be7a6cSMaksim Yevmenkin 
9907be7a6cSMaksim Yevmenkin static int32_t
lan_profile_create_service_availability(uint8_t * buf,uint8_t const * const eob,uint8_t const * data,uint32_t datalen)10007be7a6cSMaksim Yevmenkin lan_profile_create_service_availability(
10107be7a6cSMaksim Yevmenkin 		uint8_t *buf, uint8_t const * const eob,
10207be7a6cSMaksim Yevmenkin 		uint8_t const *data, uint32_t datalen)
10307be7a6cSMaksim Yevmenkin {
10407be7a6cSMaksim Yevmenkin 	provider_p		provider = (provider_p) data;
10507be7a6cSMaksim Yevmenkin 	sdp_lan_profile_p	lan = (sdp_lan_profile_p) provider->data;
10607be7a6cSMaksim Yevmenkin 
10713040bc9SMaksim Yevmenkin 	return (common_profile_create_service_availability(buf, eob,
10813040bc9SMaksim Yevmenkin 			&lan->load_factor, 1));
10907be7a6cSMaksim Yevmenkin }
11007be7a6cSMaksim Yevmenkin 
11107be7a6cSMaksim Yevmenkin static int32_t
lan_profile_create_ip_subnet(uint8_t * buf,uint8_t const * const eob,uint8_t const * data,uint32_t datalen)11207be7a6cSMaksim Yevmenkin lan_profile_create_ip_subnet(
11307be7a6cSMaksim Yevmenkin 		uint8_t *buf, uint8_t const * const eob,
11407be7a6cSMaksim Yevmenkin 		uint8_t const *data, uint32_t datalen)
11507be7a6cSMaksim Yevmenkin {
11607be7a6cSMaksim Yevmenkin 	provider_p		provider = (provider_p) data;
11707be7a6cSMaksim Yevmenkin 	sdp_lan_profile_p	lan = (sdp_lan_profile_p) provider->data;
11807be7a6cSMaksim Yevmenkin 	char			net[32];
11907be7a6cSMaksim Yevmenkin 	int32_t			len;
12007be7a6cSMaksim Yevmenkin 
12107be7a6cSMaksim Yevmenkin 	len = snprintf(net, sizeof(net), "%s/%d",
12207be7a6cSMaksim Yevmenkin 			inet_ntoa(* (struct in_addr *) &lan->ip_subnet),
12307be7a6cSMaksim Yevmenkin 			lan->ip_subnet_radius);
12407be7a6cSMaksim Yevmenkin 
12507be7a6cSMaksim Yevmenkin 	if (len < 0 || buf + 2 + len > eob)
12607be7a6cSMaksim Yevmenkin 		return (-1);
12707be7a6cSMaksim Yevmenkin 
12807be7a6cSMaksim Yevmenkin 	SDP_PUT8(SDP_DATA_STR8, buf);
12907be7a6cSMaksim Yevmenkin 	SDP_PUT8(len, buf);
13007be7a6cSMaksim Yevmenkin 	memcpy(buf, net, len);
13107be7a6cSMaksim Yevmenkin 
13207be7a6cSMaksim Yevmenkin 	return (2 + len);
13307be7a6cSMaksim Yevmenkin }
13407be7a6cSMaksim Yevmenkin 
13507be7a6cSMaksim Yevmenkin static int32_t
lan_profile_data_valid(uint8_t const * data,uint32_t datalen)13607be7a6cSMaksim Yevmenkin lan_profile_data_valid(uint8_t const *data, uint32_t datalen)
13707be7a6cSMaksim Yevmenkin {
13807be7a6cSMaksim Yevmenkin 	sdp_lan_profile_p	lan = (sdp_lan_profile_p) data;
13907be7a6cSMaksim Yevmenkin 
14007be7a6cSMaksim Yevmenkin 	if (lan->server_channel < 1 ||
14107be7a6cSMaksim Yevmenkin 	    lan->server_channel > 30 ||
14207be7a6cSMaksim Yevmenkin 	    lan->ip_subnet_radius > 32)
14307be7a6cSMaksim Yevmenkin 		return (0);
14407be7a6cSMaksim Yevmenkin 
14507be7a6cSMaksim Yevmenkin 	return (1);
14607be7a6cSMaksim Yevmenkin }
14707be7a6cSMaksim Yevmenkin 
14807be7a6cSMaksim Yevmenkin static attr_t	lan_profile_attrs[] = {
14907be7a6cSMaksim Yevmenkin 	{ SDP_ATTR_SERVICE_RECORD_HANDLE,
15007be7a6cSMaksim Yevmenkin 	  common_profile_create_service_record_handle },
15107be7a6cSMaksim Yevmenkin 	{ SDP_ATTR_SERVICE_CLASS_ID_LIST,
15207be7a6cSMaksim Yevmenkin 	  lan_profile_create_service_class_id_list },
15307be7a6cSMaksim Yevmenkin 	{ SDP_ATTR_BLUETOOTH_PROFILE_DESCRIPTOR_LIST,
15407be7a6cSMaksim Yevmenkin 	  lan_profile_create_bluetooth_profile_descriptor_list },
15507be7a6cSMaksim Yevmenkin 	{ SDP_ATTR_LANGUAGE_BASE_ATTRIBUTE_ID_LIST,
15607be7a6cSMaksim Yevmenkin 	  common_profile_create_language_base_attribute_id_list },
15707be7a6cSMaksim Yevmenkin 	{ SDP_ATTR_PRIMARY_LANGUAGE_BASE_ID + SDP_ATTR_SERVICE_NAME_OFFSET,
15807be7a6cSMaksim Yevmenkin 	  lan_profile_create_service_name },
15907be7a6cSMaksim Yevmenkin 	{ SDP_ATTR_PROTOCOL_DESCRIPTOR_LIST,
16007be7a6cSMaksim Yevmenkin 	  lan_profile_create_protocol_descriptor_list },
16107be7a6cSMaksim Yevmenkin 	{ SDP_ATTR_SERVICE_AVAILABILITY,
16207be7a6cSMaksim Yevmenkin 	  lan_profile_create_service_availability },
16307be7a6cSMaksim Yevmenkin 	{ SDP_ATTR_IP_SUBNET,
16407be7a6cSMaksim Yevmenkin 	  lan_profile_create_ip_subnet },
16507be7a6cSMaksim Yevmenkin 	{ 0, NULL } /* end entry */
16607be7a6cSMaksim Yevmenkin };
16707be7a6cSMaksim Yevmenkin 
16807be7a6cSMaksim Yevmenkin profile_t	lan_profile_descriptor = {
16907be7a6cSMaksim Yevmenkin 	SDP_SERVICE_CLASS_LAN_ACCESS_USING_PPP,
17007be7a6cSMaksim Yevmenkin 	sizeof(sdp_lan_profile_t),
17107be7a6cSMaksim Yevmenkin 	lan_profile_data_valid,
17207be7a6cSMaksim Yevmenkin 	(attr_t const * const) &lan_profile_attrs
17307be7a6cSMaksim Yevmenkin };
17407be7a6cSMaksim Yevmenkin 
175