1121054Semax/* 2121054Semax * bluetooth.c 3189462Semax */ 4189462Semax 5189462Semax/*- 6189462Semax * Copyright (c) 2001-2009 Maksim Yevmenkin <m_evmenkin@yahoo.com> 7121054Semax * All rights reserved. 8121054Semax * 9121054Semax * Redistribution and use in source and binary forms, with or without 10121054Semax * modification, are permitted provided that the following conditions 11121054Semax * are met: 12121054Semax * 1. Redistributions of source code must retain the above copyright 13121054Semax * notice, this list of conditions and the following disclaimer. 14121054Semax * 2. Redistributions in binary form must reproduce the above copyright 15121054Semax * notice, this list of conditions and the following disclaimer in the 16121054Semax * documentation and/or other materials provided with the distribution. 17121054Semax * 18121054Semax * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 19121054Semax * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20121054Semax * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21121054Semax * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 22121054Semax * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23121054Semax * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 24121054Semax * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25121054Semax * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 26121054Semax * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 27121054Semax * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 28121054Semax * SUCH DAMAGE. 29121054Semax * 30121054Semax * $Id: bluetooth.c,v 1.3 2003/05/20 23:04:30 max Exp $ 31121054Semax * $FreeBSD$ 32121054Semax */ 33281210Stakawata#define L2CAP_SOCKET_CHECKED 34121054Semax#include <bluetooth.h> 35121054Semax#include <stdio.h> 36121054Semax#include <stdlib.h> 37121054Semax#include <string.h> 38121054Semax 39121054Semax#define _PATH_BT_HOSTS "/etc/bluetooth/hosts" 40121054Semax#define _PATH_BT_PROTOCOLS "/etc/bluetooth/protocols" 41121054Semax#define MAXALIASES 35 42121054Semax 43121054Semaxstatic FILE *hostf = NULL; 44121054Semaxstatic int host_stayopen = 0; 45121054Semaxstatic struct hostent host; 46121054Semaxstatic bdaddr_t host_addr; 47121054Semaxstatic char *host_addr_ptrs[2]; 48121054Semaxstatic char *host_aliases[MAXALIASES]; 49121054Semax 50121054Semaxstatic FILE *protof = NULL; 51121054Semaxstatic int proto_stayopen = 0; 52121054Semaxstatic struct protoent proto; 53121054Semaxstatic char *proto_aliases[MAXALIASES]; 54121054Semax 55121054Semaxstatic char buf[BUFSIZ + 1]; 56121054Semax 57121054Semaxstatic int bt_hex_byte (char const *str); 58121054Semaxstatic int bt_hex_nibble (char nibble); 59121054Semax 60121054Semaxstruct hostent * 61121054Semaxbt_gethostbyname(char const *name) 62121054Semax{ 63121054Semax struct hostent *p; 64121054Semax char **cp; 65121054Semax 66121054Semax bt_sethostent(host_stayopen); 67121054Semax while ((p = bt_gethostent()) != NULL) { 68121054Semax if (strcasecmp(p->h_name, name) == 0) 69121054Semax break; 70298208Spfg for (cp = p->h_aliases; *cp != NULL; cp++) 71121054Semax if (strcasecmp(*cp, name) == 0) 72121054Semax goto found; 73121054Semax } 74121054Semaxfound: 75121054Semax bt_endhostent(); 76121054Semax 77121054Semax return (p); 78121054Semax} 79121054Semax 80121054Semaxstruct hostent * 81121054Semaxbt_gethostbyaddr(char const *addr, int len, int type) 82121054Semax{ 83121054Semax struct hostent *p; 84121054Semax 85121054Semax if (type != AF_BLUETOOTH || len != sizeof(bdaddr_t)) { 86121054Semax h_errno = NO_RECOVERY; 87121054Semax return (NULL); 88121054Semax } 89121054Semax 90121054Semax bt_sethostent(host_stayopen); 91121054Semax while ((p = bt_gethostent()) != NULL) 92121054Semax if (p->h_addrtype == type && bcmp(p->h_addr, addr, len) == 0) 93121054Semax break; 94121054Semax bt_endhostent(); 95121054Semax 96121054Semax return (p); 97121054Semax} 98121054Semax 99121054Semaxstruct hostent * 100121054Semaxbt_gethostent(void) 101121054Semax{ 102121054Semax char *p, *cp, **q; 103121054Semax 104121054Semax if (hostf == NULL) 105121054Semax hostf = fopen(_PATH_BT_HOSTS, "r"); 106121054Semax 107121054Semax if (hostf == NULL) { 108121054Semax h_errno = NETDB_INTERNAL; 109121054Semax return (NULL); 110121054Semax } 111121054Semaxagain: 112121054Semax if ((p = fgets(buf, sizeof(buf), hostf)) == NULL) { 113121054Semax h_errno = HOST_NOT_FOUND; 114121054Semax return (NULL); 115121054Semax } 116121054Semax if (*p == '#') 117121054Semax goto again; 118121054Semax if ((cp = strpbrk(p, "#\n")) == NULL) 119121054Semax goto again; 120121054Semax *cp = 0; 121121054Semax if ((cp = strpbrk(p, " \t")) == NULL) 122121054Semax goto again; 123121054Semax *cp++ = 0; 124121054Semax if (bt_aton(p, &host_addr) == 0) 125121054Semax goto again; 126121054Semax host_addr_ptrs[0] = (char *) &host_addr; 127121054Semax host_addr_ptrs[1] = NULL; 128121054Semax host.h_addr_list = host_addr_ptrs; 129121054Semax host.h_length = sizeof(host_addr); 130121054Semax host.h_addrtype = AF_BLUETOOTH; 131121054Semax while (*cp == ' ' || *cp == '\t') 132121054Semax cp++; 133121054Semax host.h_name = cp; 134121054Semax q = host.h_aliases = host_aliases; 135121054Semax if ((cp = strpbrk(cp, " \t")) != NULL) 136121054Semax *cp++ = 0; 137121054Semax while (cp != NULL && *cp != 0) { 138121054Semax if (*cp == ' ' || *cp == '\t') { 139121054Semax cp++; 140121054Semax continue; 141121054Semax } 142121054Semax if (q < &host_aliases[MAXALIASES - 1]) 143121054Semax *q++ = cp; 144121054Semax if ((cp = strpbrk(cp, " \t")) != NULL) 145121054Semax *cp++ = 0; 146121054Semax } 147121054Semax *q = NULL; 148121054Semax h_errno = NETDB_SUCCESS; 149121054Semax 150121054Semax return (&host); 151121054Semax} 152121054Semax 153121054Semaxvoid 154121054Semaxbt_sethostent(int stayopen) 155121054Semax{ 156121054Semax if (hostf == NULL) 157121054Semax hostf = fopen(_PATH_BT_HOSTS, "r"); 158121054Semax else 159121054Semax rewind(hostf); 160121054Semax 161121054Semax host_stayopen = stayopen; 162121054Semax} 163121054Semax 164121054Semaxvoid 165121054Semaxbt_endhostent(void) 166121054Semax{ 167121054Semax if (hostf != NULL && host_stayopen == 0) { 168121054Semax (void) fclose(hostf); 169121054Semax hostf = NULL; 170121054Semax } 171121054Semax} 172121054Semax 173121054Semaxstruct protoent * 174121054Semaxbt_getprotobyname(char const *name) 175121054Semax{ 176121054Semax struct protoent *p; 177121054Semax char **cp; 178121054Semax 179121054Semax bt_setprotoent(proto_stayopen); 180121054Semax while ((p = bt_getprotoent()) != NULL) { 181121054Semax if (strcmp(p->p_name, name) == 0) 182121054Semax break; 183298208Spfg for (cp = p->p_aliases; *cp != NULL; cp++) 184121054Semax if (strcmp(*cp, name) == 0) 185121054Semax goto found; 186121054Semax } 187121054Semaxfound: 188121054Semax bt_endprotoent(); 189121054Semax 190121054Semax return (p); 191121054Semax} 192121054Semax 193121054Semaxstruct protoent * 194121054Semaxbt_getprotobynumber(int proto) 195121054Semax{ 196121054Semax struct protoent *p; 197121054Semax 198121054Semax bt_setprotoent(proto_stayopen); 199121054Semax while ((p = bt_getprotoent()) != NULL) 200121054Semax if (p->p_proto == proto) 201121054Semax break; 202121054Semax bt_endprotoent(); 203121054Semax 204121054Semax return (p); 205121054Semax} 206121054Semax 207121054Semaxstruct protoent * 208121054Semaxbt_getprotoent(void) 209121054Semax{ 210121054Semax char *p, *cp, **q; 211121054Semax 212121054Semax if (protof == NULL) 213121054Semax protof = fopen(_PATH_BT_PROTOCOLS, "r"); 214121054Semax 215121054Semax if (protof == NULL) 216121054Semax return (NULL); 217121054Semaxagain: 218121054Semax if ((p = fgets(buf, sizeof(buf), protof)) == NULL) 219121054Semax return (NULL); 220121054Semax if (*p == '#') 221121054Semax goto again; 222121054Semax if ((cp = strpbrk(p, "#\n")) == NULL) 223121054Semax goto again; 224121054Semax *cp = '\0'; 225121054Semax proto.p_name = p; 226121054Semax if ((cp = strpbrk(p, " \t")) == NULL) 227121054Semax goto again; 228121054Semax *cp++ = '\0'; 229121054Semax while (*cp == ' ' || *cp == '\t') 230121054Semax cp++; 231121054Semax if ((p = strpbrk(cp, " \t")) != NULL) 232121054Semax *p++ = '\0'; 233121054Semax proto.p_proto = atoi(cp); 234121054Semax q = proto.p_aliases = proto_aliases; 235121054Semax if (p != NULL) { 236121054Semax cp = p; 237121054Semax while (cp != NULL && *cp != 0) { 238121054Semax if (*cp == ' ' || *cp == '\t') { 239121054Semax cp++; 240121054Semax continue; 241121054Semax } 242121054Semax if (q < &proto_aliases[MAXALIASES - 1]) 243121054Semax *q++ = cp; 244121054Semax if ((cp = strpbrk(cp, " \t")) != NULL) 245121054Semax *cp++ = '\0'; 246121054Semax } 247121054Semax } 248121054Semax *q = NULL; 249121054Semax 250121054Semax return (&proto); 251121054Semax} 252121054Semax 253121054Semaxvoid 254121054Semaxbt_setprotoent(int stayopen) 255121054Semax{ 256121054Semax if (protof == NULL) 257121054Semax protof = fopen(_PATH_BT_PROTOCOLS, "r"); 258121054Semax else 259121054Semax rewind(protof); 260121054Semax 261121054Semax proto_stayopen = stayopen; 262121054Semax} 263121054Semax 264121054Semaxvoid 265121054Semaxbt_endprotoent(void) 266121054Semax{ 267121054Semax if (protof != NULL) { 268121054Semax (void) fclose(protof); 269121054Semax protof = NULL; 270121054Semax } 271121054Semax} 272121054Semax 273121054Semaxchar const * 274121054Semaxbt_ntoa(bdaddr_t const *ba, char *str) 275121054Semax{ 276121054Semax static char buffer[24]; 277121054Semax 278121054Semax if (str == NULL) 279121054Semax str = buffer; 280121054Semax 281121054Semax sprintf(str, "%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x", 282121054Semax ba->b[5], ba->b[4], ba->b[3], ba->b[2], ba->b[1], ba->b[0]); 283121054Semax 284121054Semax return (str); 285121054Semax} 286121054Semax 287121054Semaxint 288121054Semaxbt_aton(char const *str, bdaddr_t *ba) 289121054Semax{ 290121054Semax int i, b; 291121054Semax char *end = NULL; 292121054Semax 293121054Semax memset(ba, 0, sizeof(*ba)); 294121054Semax 295121054Semax for (i = 5, end = strchr(str, ':'); 296126643Smarkm i > 0 && *str != '\0' && end != NULL; 297121054Semax i --, str = end + 1, end = strchr(str, ':')) { 298121054Semax switch (end - str) { 299121054Semax case 1: 300121054Semax b = bt_hex_nibble(str[0]); 301121054Semax break; 302121054Semax 303121054Semax case 2: 304121054Semax b = bt_hex_byte(str); 305121054Semax break; 306121054Semax 307121054Semax default: 308121054Semax b = -1; 309121054Semax break; 310121054Semax } 311121054Semax 312121054Semax if (b < 0) 313121054Semax return (0); 314121054Semax 315121054Semax ba->b[i] = b; 316121054Semax } 317121054Semax 318121054Semax if (i != 0 || end != NULL || *str == 0) 319121054Semax return (0); 320121054Semax 321121054Semax switch (strlen(str)) { 322121054Semax case 1: 323121054Semax b = bt_hex_nibble(str[0]); 324121054Semax break; 325121054Semax 326121054Semax case 2: 327121054Semax b = bt_hex_byte(str); 328121054Semax break; 329121054Semax 330121054Semax default: 331121054Semax b = -1; 332121054Semax break; 333121054Semax } 334121054Semax 335121054Semax if (b < 0) 336121054Semax return (0); 337121054Semax 338121054Semax ba->b[i] = b; 339121054Semax 340121054Semax return (1); 341121054Semax} 342121054Semax 343121054Semaxstatic int 344121054Semaxbt_hex_byte(char const *str) 345121054Semax{ 346121054Semax int n1, n2; 347121054Semax 348121054Semax if ((n1 = bt_hex_nibble(str[0])) < 0) 349121054Semax return (-1); 350121054Semax 351121054Semax if ((n2 = bt_hex_nibble(str[1])) < 0) 352121054Semax return (-1); 353121054Semax 354121054Semax return ((((n1 & 0x0f) << 4) | (n2 & 0x0f)) & 0xff); 355121054Semax} 356121054Semax 357121054Semaxstatic int 358121054Semaxbt_hex_nibble(char nibble) 359121054Semax{ 360121054Semax if ('0' <= nibble && nibble <= '9') 361121054Semax return (nibble - '0'); 362121054Semax 363121054Semax if ('a' <= nibble && nibble <= 'f') 364121054Semax return (nibble - 'a' + 0xa); 365121054Semax 366121054Semax if ('A' <= nibble && nibble <= 'F') 367121054Semax return (nibble - 'A' + 0xa); 368121054Semax 369121054Semax return (-1); 370121054Semax} 371121054Semax 372