]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - lib/libbluetooth/bluetooth.c
Make linux_ptrace() use linux_msg() instead of printf().
[FreeBSD/FreeBSD.git] / lib / libbluetooth / bluetooth.c
1 /*
2  * bluetooth.c
3  */
4
5 /*-
6  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
7  *
8  * Copyright (c) 2001-2009 Maksim Yevmenkin <m_evmenkin@yahoo.com>
9  * All rights reserved.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions
13  * are met:
14  * 1. Redistributions of source code must retain the above copyright
15  *    notice, this list of conditions and the following disclaimer.
16  * 2. Redistributions in binary form must reproduce the above copyright
17  *    notice, this list of conditions and the following disclaimer in the
18  *    documentation and/or other materials provided with the distribution.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
21  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
24  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30  * SUCH DAMAGE.
31  *
32  * $Id: bluetooth.c,v 1.3 2003/05/20 23:04:30 max Exp $
33  * $FreeBSD$
34  */
35 #define L2CAP_SOCKET_CHECKED
36 #include <bluetooth.h>
37 #include <stdio.h>
38 #include <stdlib.h>
39 #include <string.h>
40
41 #define _PATH_BT_HOSTS          "/etc/bluetooth/hosts"
42 #define _PATH_BT_PROTOCOLS      "/etc/bluetooth/protocols"
43 #define MAXALIASES               35
44
45 static FILE             *hostf = NULL;
46 static int               host_stayopen = 0;
47 static struct hostent    host;
48 static bdaddr_t          host_addr;
49 static char             *host_addr_ptrs[2];
50 static char             *host_aliases[MAXALIASES];
51
52 static FILE             *protof = NULL;
53 static int               proto_stayopen = 0;
54 static struct protoent   proto;
55 static char             *proto_aliases[MAXALIASES];
56
57 static char              buf[BUFSIZ + 1];
58
59 static int bt_hex_byte   (char const *str);
60 static int bt_hex_nibble (char nibble);
61
62 struct hostent *
63 bt_gethostbyname(char const *name)
64 {
65         struct hostent  *p;
66         char            **cp;
67
68         bt_sethostent(host_stayopen);
69         while ((p = bt_gethostent()) != NULL) {
70                 if (strcasecmp(p->h_name, name) == 0)
71                         break;
72                 for (cp = p->h_aliases; *cp != NULL; cp++)
73                         if (strcasecmp(*cp, name) == 0)
74                                 goto found;
75         }
76 found:
77         bt_endhostent();
78
79         return (p);
80 }
81
82 struct hostent *
83 bt_gethostbyaddr(char const *addr, int len, int type)
84 {
85         struct hostent  *p;
86
87         if (type != AF_BLUETOOTH || len != sizeof(bdaddr_t)) {
88                 h_errno = NO_RECOVERY;
89                 return (NULL);
90         }
91
92         bt_sethostent(host_stayopen);
93         while ((p = bt_gethostent()) != NULL)
94                 if (p->h_addrtype == type && bcmp(p->h_addr, addr, len) == 0)
95                         break;
96         bt_endhostent();
97
98         return (p);
99 }
100
101 struct hostent *
102 bt_gethostent(void)
103 {
104         char    *p, *cp, **q;
105
106         if (hostf == NULL)
107                 hostf = fopen(_PATH_BT_HOSTS, "r");
108
109         if (hostf == NULL) {
110                 h_errno = NETDB_INTERNAL;
111                 return (NULL);
112         }
113 again:
114         if ((p = fgets(buf, sizeof(buf), hostf)) == NULL) {
115                 h_errno = HOST_NOT_FOUND;
116                 return (NULL);
117         }
118         if (*p == '#')
119                 goto again;
120         if ((cp = strpbrk(p, "#\n")) == NULL)
121                 goto again;
122         *cp = 0;
123         if ((cp = strpbrk(p, " \t")) == NULL)
124                 goto again;
125         *cp++ = 0;
126         if (bt_aton(p, &host_addr) == 0) 
127                 goto again;
128         host_addr_ptrs[0] = (char *) &host_addr;
129         host_addr_ptrs[1] = NULL;
130         host.h_addr_list = host_addr_ptrs;
131         host.h_length = sizeof(host_addr);
132         host.h_addrtype = AF_BLUETOOTH;
133         while (*cp == ' ' || *cp == '\t')
134                 cp++;
135         host.h_name = cp;
136         q = host.h_aliases = host_aliases;
137         if ((cp = strpbrk(cp, " \t")) != NULL)
138                 *cp++ = 0;
139         while (cp != NULL && *cp != 0) {
140                 if (*cp == ' ' || *cp == '\t') {
141                         cp++;
142                         continue;
143                 }
144                 if (q < &host_aliases[MAXALIASES - 1])
145                         *q++ = cp;
146                 if ((cp = strpbrk(cp, " \t")) != NULL)
147                         *cp++ = 0;
148         }
149         *q = NULL;
150         h_errno = NETDB_SUCCESS;
151
152         return (&host);
153 }
154
155 void
156 bt_sethostent(int stayopen)
157 {
158         if (hostf == NULL)
159                 hostf = fopen(_PATH_BT_HOSTS, "r");
160         else
161                 rewind(hostf);
162
163         host_stayopen = stayopen;
164 }
165
166 void
167 bt_endhostent(void)
168 {
169         if (hostf != NULL && host_stayopen == 0) {
170                 (void) fclose(hostf);
171                 hostf = NULL;
172         }
173 }
174
175 struct protoent *
176 bt_getprotobyname(char const *name)
177 {
178         struct protoent  *p;
179         char            **cp;
180
181         bt_setprotoent(proto_stayopen);
182         while ((p = bt_getprotoent()) != NULL) {
183                 if (strcmp(p->p_name, name) == 0)
184                         break;
185                 for (cp = p->p_aliases; *cp != NULL; cp++)
186                         if (strcmp(*cp, name) == 0)
187                                 goto found;
188         }
189 found:
190         bt_endprotoent();
191
192         return (p);
193 }
194
195 struct protoent *
196 bt_getprotobynumber(int proto)
197 {
198         struct protoent *p;
199
200         bt_setprotoent(proto_stayopen);
201         while ((p = bt_getprotoent()) != NULL)
202                 if (p->p_proto == proto)
203                         break;
204         bt_endprotoent();
205
206         return (p);
207 }
208
209 struct protoent *
210 bt_getprotoent(void)
211 {
212         char    *p, *cp, **q;
213
214         if (protof == NULL)
215                 protof = fopen(_PATH_BT_PROTOCOLS, "r");
216
217         if (protof == NULL)
218                 return (NULL);
219 again:
220         if ((p = fgets(buf, sizeof(buf), protof)) == NULL)
221                 return (NULL);
222         if (*p == '#')
223                 goto again;
224         if ((cp = strpbrk(p, "#\n")) == NULL)
225                 goto again;
226         *cp = '\0';
227         proto.p_name = p;
228         if ((cp = strpbrk(p, " \t")) == NULL)
229                 goto again;
230         *cp++ = '\0';
231         while (*cp == ' ' || *cp == '\t')
232                 cp++;
233         if ((p = strpbrk(cp, " \t")) != NULL)
234                 *p++ = '\0';
235         proto.p_proto = atoi(cp);
236         q = proto.p_aliases = proto_aliases;
237         if (p != NULL) {
238                 cp = p;
239                 while (cp != NULL && *cp != 0) {
240                         if (*cp == ' ' || *cp == '\t') {
241                                 cp++;
242                                 continue;
243                         }
244                         if (q < &proto_aliases[MAXALIASES - 1])
245                                 *q++ = cp;
246                         if ((cp = strpbrk(cp, " \t")) != NULL)
247                                 *cp++ = '\0';
248                 }
249         }
250         *q = NULL;
251
252         return (&proto);
253 }
254
255 void
256 bt_setprotoent(int stayopen)
257 {
258         if (protof == NULL)
259                 protof = fopen(_PATH_BT_PROTOCOLS, "r");
260         else
261                 rewind(protof);
262
263         proto_stayopen = stayopen;
264 }
265
266 void
267 bt_endprotoent(void)
268 {
269         if (protof != NULL) {
270                 (void) fclose(protof);
271                 protof = NULL;
272         }
273 }
274
275 char const *
276 bt_ntoa(bdaddr_t const *ba, char *str)
277 {
278         static char     buffer[24];
279
280         if (str == NULL)
281                 str = buffer;
282
283         sprintf(str, "%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x",
284                 ba->b[5], ba->b[4], ba->b[3], ba->b[2], ba->b[1], ba->b[0]);
285
286         return (str);
287 }
288
289 int
290 bt_aton(char const *str, bdaddr_t *ba)
291 {
292         int      i, b;
293         char    *end = NULL;
294
295         memset(ba, 0, sizeof(*ba));
296
297         for (i = 5, end = strchr(str, ':');
298              i > 0 && *str != '\0' && end != NULL;
299              i --, str = end + 1, end = strchr(str, ':')) {
300                 switch (end - str) {
301                 case 1:
302                         b = bt_hex_nibble(str[0]);
303                         break;
304
305                 case 2:
306                         b = bt_hex_byte(str);
307                         break;
308
309                 default:
310                         b = -1;
311                         break;
312                 }
313                 
314                 if (b < 0)
315                         return (0);
316
317                 ba->b[i] = b;
318         }
319
320         if (i != 0 || end != NULL || *str == 0)
321                 return (0);
322
323         switch (strlen(str)) {
324         case 1:
325                 b = bt_hex_nibble(str[0]);
326                 break;
327
328         case 2:
329                 b = bt_hex_byte(str);
330                 break;
331
332         default:
333                 b = -1;
334                 break;
335         }
336
337         if (b < 0)
338                 return (0);
339
340         ba->b[i] = b;
341
342         return (1);
343 }
344
345 static int
346 bt_hex_byte(char const *str)
347 {
348         int     n1, n2;
349
350         if ((n1 = bt_hex_nibble(str[0])) < 0)
351                 return (-1);
352
353         if ((n2 = bt_hex_nibble(str[1])) < 0)
354                 return (-1);
355
356         return ((((n1 & 0x0f) << 4) | (n2 & 0x0f)) & 0xff);
357 }
358
359 static int
360 bt_hex_nibble(char nibble)
361 {
362         if ('0' <= nibble && nibble <= '9')
363                 return (nibble - '0');
364
365         if ('a' <= nibble && nibble <= 'f')
366                 return (nibble - 'a' + 0xa);
367
368         if ('A' <= nibble && nibble <= 'F')
369                 return (nibble - 'A' + 0xa);
370
371         return (-1);
372 }
373