xref: /dflybsd-src/lib/libbluetooth/bluetooth.c (revision a632cd2d33eae3cdf365948061576a303057c733)
137f60ad1SHasso Tepper /* $NetBSD: bluetooth.c,v 1.1 2006/06/19 15:44:36 gdamore Exp $ */
237f60ad1SHasso Tepper 
337f60ad1SHasso Tepper /*
437f60ad1SHasso Tepper  * bluetooth.c
537f60ad1SHasso Tepper  *
637f60ad1SHasso Tepper  * Copyright (c) 2001-2003 Maksim Yevmenkin <m_evmenkin@yahoo.com>
737f60ad1SHasso Tepper  * All rights reserved.
837f60ad1SHasso Tepper  *
937f60ad1SHasso Tepper  * Redistribution and use in source and binary forms, with or without
1037f60ad1SHasso Tepper  * modification, are permitted provided that the following conditions
1137f60ad1SHasso Tepper  * are met:
1237f60ad1SHasso Tepper  * 1. Redistributions of source code must retain the above copyright
1337f60ad1SHasso Tepper  *    notice, this list of conditions and the following disclaimer.
1437f60ad1SHasso Tepper  * 2. Redistributions in binary form must reproduce the above copyright
1537f60ad1SHasso Tepper  *    notice, this list of conditions and the following disclaimer in the
1637f60ad1SHasso Tepper  *    documentation and/or other materials provided with the distribution.
1737f60ad1SHasso Tepper  *
1837f60ad1SHasso Tepper  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1937f60ad1SHasso Tepper  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2037f60ad1SHasso Tepper  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2137f60ad1SHasso Tepper  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
2237f60ad1SHasso Tepper  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2337f60ad1SHasso Tepper  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2437f60ad1SHasso Tepper  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2537f60ad1SHasso Tepper  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2637f60ad1SHasso Tepper  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2737f60ad1SHasso Tepper  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2837f60ad1SHasso Tepper  * SUCH DAMAGE.
2937f60ad1SHasso Tepper  *
3037f60ad1SHasso Tepper  * $Id: bluetooth.c,v 1.1 2006/06/19 15:44:36 gdamore Exp $
3137f60ad1SHasso Tepper  * $FreeBSD: src/lib/libbluetooth/bluetooth.c,v 1.2 2004/03/05 08:10:17 markm Exp $
3237f60ad1SHasso Tepper  */
3337f60ad1SHasso Tepper 
3437f60ad1SHasso Tepper #include <bluetooth.h>
3537f60ad1SHasso Tepper #include <stdio.h>
3637f60ad1SHasso Tepper #include <stdlib.h>
3737f60ad1SHasso Tepper #include <string.h>
3837f60ad1SHasso Tepper 
3937f60ad1SHasso Tepper #define _PATH_BT_HOSTS		"/etc/bluetooth/hosts"
4037f60ad1SHasso Tepper #define _PATH_BT_PROTOCOLS	"/etc/bluetooth/protocols"
4137f60ad1SHasso Tepper #define MAXALIASES		 35
4237f60ad1SHasso Tepper 
4337f60ad1SHasso Tepper static FILE		*hostf = NULL;
4437f60ad1SHasso Tepper static int		 host_stayopen = 0;
4537f60ad1SHasso Tepper static struct hostent	 host;
4637f60ad1SHasso Tepper static bdaddr_t		 host_addr;
4737f60ad1SHasso Tepper static char		*host_addr_ptrs[2];
4837f60ad1SHasso Tepper static char		*host_aliases[MAXALIASES];
4937f60ad1SHasso Tepper 
5037f60ad1SHasso Tepper static FILE		*protof = NULL;
5137f60ad1SHasso Tepper static int		 proto_stayopen = 0;
5237f60ad1SHasso Tepper static struct protoent	 proto;
5337f60ad1SHasso Tepper static char		*proto_aliases[MAXALIASES];
5437f60ad1SHasso Tepper 
5537f60ad1SHasso Tepper static char		 buf[BUFSIZ + 1];
5637f60ad1SHasso Tepper 
5737f60ad1SHasso Tepper static int bt_hex_byte   (char const *str);
5837f60ad1SHasso Tepper static int bt_hex_nibble (char nibble);
5937f60ad1SHasso Tepper 
6037f60ad1SHasso Tepper struct hostent *
bt_gethostbyname(char const * name)6137f60ad1SHasso Tepper bt_gethostbyname(char const *name)
6237f60ad1SHasso Tepper {
6337f60ad1SHasso Tepper 	struct hostent	*p;
6437f60ad1SHasso Tepper 	char		**cp;
6537f60ad1SHasso Tepper 
6637f60ad1SHasso Tepper 	bt_sethostent(host_stayopen);
6737f60ad1SHasso Tepper 	while ((p = bt_gethostent()) != NULL) {
6837f60ad1SHasso Tepper 		if (strcasecmp(p->h_name, name) == 0)
6937f60ad1SHasso Tepper 			break;
70*678e8cc6SSascha Wildner 		for (cp = p->h_aliases; *cp != NULL; cp++)
7137f60ad1SHasso Tepper 			if (strcasecmp(*cp, name) == 0)
7237f60ad1SHasso Tepper 				goto found;
7337f60ad1SHasso Tepper 	}
7437f60ad1SHasso Tepper found:
7537f60ad1SHasso Tepper 	bt_endhostent();
7637f60ad1SHasso Tepper 
7737f60ad1SHasso Tepper 	return (p);
7837f60ad1SHasso Tepper }
7937f60ad1SHasso Tepper 
8037f60ad1SHasso Tepper struct hostent *
bt_gethostbyaddr(void const * addr,socklen_t len,int type)8163bd4a35SSascha Wildner bt_gethostbyaddr(void const *addr, socklen_t len, int type)
8237f60ad1SHasso Tepper {
8337f60ad1SHasso Tepper 	struct hostent	*p;
8437f60ad1SHasso Tepper 
8537f60ad1SHasso Tepper 	if (type != AF_BLUETOOTH || len != sizeof(bdaddr_t)) {
8637f60ad1SHasso Tepper 		h_errno = NO_RECOVERY;
8737f60ad1SHasso Tepper 		return (NULL);
8837f60ad1SHasso Tepper 	}
8937f60ad1SHasso Tepper 
9037f60ad1SHasso Tepper 	bt_sethostent(host_stayopen);
9137f60ad1SHasso Tepper 	while ((p = bt_gethostent()) != NULL)
9237f60ad1SHasso Tepper 		if (p->h_addrtype == type && memcmp(p->h_addr, addr, len) == 0)
9337f60ad1SHasso Tepper 			break;
9437f60ad1SHasso Tepper 	bt_endhostent();
9537f60ad1SHasso Tepper 
9637f60ad1SHasso Tepper 	return (p);
9737f60ad1SHasso Tepper }
9837f60ad1SHasso Tepper 
9937f60ad1SHasso Tepper struct hostent *
bt_gethostent(void)10037f60ad1SHasso Tepper bt_gethostent(void)
10137f60ad1SHasso Tepper {
10237f60ad1SHasso Tepper 	char	*p, *cp, **q;
10337f60ad1SHasso Tepper 
10437f60ad1SHasso Tepper 	if (hostf == NULL)
10537f60ad1SHasso Tepper 		hostf = fopen(_PATH_BT_HOSTS, "r");
10637f60ad1SHasso Tepper 
10737f60ad1SHasso Tepper 	if (hostf == NULL) {
10837f60ad1SHasso Tepper 		h_errno = NETDB_INTERNAL;
10937f60ad1SHasso Tepper 		return (NULL);
11037f60ad1SHasso Tepper 	}
11137f60ad1SHasso Tepper again:
11237f60ad1SHasso Tepper 	if ((p = fgets(buf, sizeof(buf), hostf)) == NULL) {
11337f60ad1SHasso Tepper 		h_errno = HOST_NOT_FOUND;
11437f60ad1SHasso Tepper 		return (NULL);
11537f60ad1SHasso Tepper 	}
11637f60ad1SHasso Tepper 	if (*p == '#')
11737f60ad1SHasso Tepper 		goto again;
11837f60ad1SHasso Tepper 	if ((cp = strpbrk(p, "#\n")) == NULL)
11937f60ad1SHasso Tepper 		goto again;
12037f60ad1SHasso Tepper 	*cp = 0;
12137f60ad1SHasso Tepper 	if ((cp = strpbrk(p, " \t")) == NULL)
12237f60ad1SHasso Tepper 		goto again;
12337f60ad1SHasso Tepper 	*cp++ = 0;
12437f60ad1SHasso Tepper 	if (bt_aton(p, &host_addr) == 0)
12537f60ad1SHasso Tepper 		goto again;
12637f60ad1SHasso Tepper 	host_addr_ptrs[0] = (char *) &host_addr;
12737f60ad1SHasso Tepper 	host_addr_ptrs[1] = NULL;
12837f60ad1SHasso Tepper 	host.h_addr_list = host_addr_ptrs;
12937f60ad1SHasso Tepper 	host.h_length = sizeof(host_addr);
13037f60ad1SHasso Tepper 	host.h_addrtype = AF_BLUETOOTH;
13137f60ad1SHasso Tepper 	while (*cp == ' ' || *cp == '\t')
13237f60ad1SHasso Tepper 		cp++;
13337f60ad1SHasso Tepper 	host.h_name = cp;
13437f60ad1SHasso Tepper 	q = host.h_aliases = host_aliases;
13537f60ad1SHasso Tepper 	if ((cp = strpbrk(cp, " \t")) != NULL)
13637f60ad1SHasso Tepper 		*cp++ = 0;
13737f60ad1SHasso Tepper 	while (cp != NULL && *cp != 0) {
13837f60ad1SHasso Tepper 		if (*cp == ' ' || *cp == '\t') {
13937f60ad1SHasso Tepper 			cp++;
14037f60ad1SHasso Tepper 			continue;
14137f60ad1SHasso Tepper 		}
14237f60ad1SHasso Tepper 		if (q < &host_aliases[MAXALIASES - 1])
14337f60ad1SHasso Tepper 			*q++ = cp;
14437f60ad1SHasso Tepper 		if ((cp = strpbrk(cp, " \t")) != NULL)
14537f60ad1SHasso Tepper 			*cp++ = 0;
14637f60ad1SHasso Tepper 	}
14737f60ad1SHasso Tepper 	*q = NULL;
14837f60ad1SHasso Tepper 	h_errno = NETDB_SUCCESS;
14937f60ad1SHasso Tepper 
15037f60ad1SHasso Tepper 	return (&host);
15137f60ad1SHasso Tepper }
15237f60ad1SHasso Tepper 
15337f60ad1SHasso Tepper void
bt_sethostent(int stayopen)15437f60ad1SHasso Tepper bt_sethostent(int stayopen)
15537f60ad1SHasso Tepper {
15637f60ad1SHasso Tepper 	if (hostf == NULL)
15737f60ad1SHasso Tepper 		hostf = fopen(_PATH_BT_HOSTS, "r");
15837f60ad1SHasso Tepper 	else
15937f60ad1SHasso Tepper 		rewind(hostf);
16037f60ad1SHasso Tepper 
16137f60ad1SHasso Tepper 	host_stayopen = stayopen;
16237f60ad1SHasso Tepper }
16337f60ad1SHasso Tepper 
16437f60ad1SHasso Tepper void
bt_endhostent(void)16537f60ad1SHasso Tepper bt_endhostent(void)
16637f60ad1SHasso Tepper {
16737f60ad1SHasso Tepper 	if (hostf != NULL && host_stayopen == 0) {
16837f60ad1SHasso Tepper 		(void) fclose(hostf);
16937f60ad1SHasso Tepper 		hostf = NULL;
17037f60ad1SHasso Tepper 	}
17137f60ad1SHasso Tepper }
17237f60ad1SHasso Tepper 
17337f60ad1SHasso Tepper struct protoent *
bt_getprotobyname(char const * name)17437f60ad1SHasso Tepper bt_getprotobyname(char const *name)
17537f60ad1SHasso Tepper {
17637f60ad1SHasso Tepper 	struct protoent	 *p;
17737f60ad1SHasso Tepper 	char		**cp;
17837f60ad1SHasso Tepper 
17937f60ad1SHasso Tepper 	bt_setprotoent(proto_stayopen);
18037f60ad1SHasso Tepper 	while ((p = bt_getprotoent()) != NULL) {
18137f60ad1SHasso Tepper 		if (strcmp(p->p_name, name) == 0)
18237f60ad1SHasso Tepper 			break;
183*678e8cc6SSascha Wildner 		for (cp = p->p_aliases; *cp != NULL; cp++)
18437f60ad1SHasso Tepper 			if (strcmp(*cp, name) == 0)
18537f60ad1SHasso Tepper 				goto found;
18637f60ad1SHasso Tepper 	}
18737f60ad1SHasso Tepper found:
18837f60ad1SHasso Tepper 	bt_endprotoent();
18937f60ad1SHasso Tepper 
19037f60ad1SHasso Tepper 	return (p);
19137f60ad1SHasso Tepper }
19237f60ad1SHasso Tepper 
19337f60ad1SHasso Tepper struct protoent *
bt_getprotobynumber(int num)19437f60ad1SHasso Tepper bt_getprotobynumber(int num)
19537f60ad1SHasso Tepper {
19637f60ad1SHasso Tepper 	struct protoent	*p;
19737f60ad1SHasso Tepper 
19837f60ad1SHasso Tepper 	bt_setprotoent(proto_stayopen);
19937f60ad1SHasso Tepper 	while ((p = bt_getprotoent()) != NULL)
20037f60ad1SHasso Tepper 		if (p->p_proto == num)
20137f60ad1SHasso Tepper 			break;
20237f60ad1SHasso Tepper 	bt_endprotoent();
20337f60ad1SHasso Tepper 
20437f60ad1SHasso Tepper 	return (p);
20537f60ad1SHasso Tepper }
20637f60ad1SHasso Tepper 
20737f60ad1SHasso Tepper struct protoent *
bt_getprotoent(void)20837f60ad1SHasso Tepper bt_getprotoent(void)
20937f60ad1SHasso Tepper {
21037f60ad1SHasso Tepper 	char	*p, *cp, **q;
21137f60ad1SHasso Tepper 
21237f60ad1SHasso Tepper 	if (protof == NULL)
21337f60ad1SHasso Tepper 		protof = fopen(_PATH_BT_PROTOCOLS, "r");
21437f60ad1SHasso Tepper 
21537f60ad1SHasso Tepper 	if (protof == NULL)
21637f60ad1SHasso Tepper 		return (NULL);
21737f60ad1SHasso Tepper again:
21837f60ad1SHasso Tepper 	if ((p = fgets(buf, sizeof(buf), protof)) == NULL)
21937f60ad1SHasso Tepper 		return (NULL);
22037f60ad1SHasso Tepper 	if (*p == '#')
22137f60ad1SHasso Tepper 		goto again;
22237f60ad1SHasso Tepper 	if ((cp = strpbrk(p, "#\n")) == NULL)
22337f60ad1SHasso Tepper 		goto again;
22437f60ad1SHasso Tepper 	*cp = '\0';
22537f60ad1SHasso Tepper 	proto.p_name = p;
22637f60ad1SHasso Tepper 	if ((cp = strpbrk(p, " \t")) == NULL)
22737f60ad1SHasso Tepper 		goto again;
22837f60ad1SHasso Tepper 	*cp++ = '\0';
22937f60ad1SHasso Tepper 	while (*cp == ' ' || *cp == '\t')
23037f60ad1SHasso Tepper 		cp++;
23137f60ad1SHasso Tepper 	if ((p = strpbrk(cp, " \t")) != NULL)
23237f60ad1SHasso Tepper 		*p++ = '\0';
23337f60ad1SHasso Tepper 	proto.p_proto = (int)strtol(cp, NULL, 0);
23437f60ad1SHasso Tepper 	q = proto.p_aliases = proto_aliases;
23537f60ad1SHasso Tepper 	if (p != NULL) {
23637f60ad1SHasso Tepper 		cp = p;
23737f60ad1SHasso Tepper 		while (cp != NULL && *cp != 0) {
23837f60ad1SHasso Tepper 			if (*cp == ' ' || *cp == '\t') {
23937f60ad1SHasso Tepper 				cp++;
24037f60ad1SHasso Tepper 				continue;
24137f60ad1SHasso Tepper 			}
24237f60ad1SHasso Tepper 			if (q < &proto_aliases[MAXALIASES - 1])
24337f60ad1SHasso Tepper 				*q++ = cp;
24437f60ad1SHasso Tepper 			if ((cp = strpbrk(cp, " \t")) != NULL)
24537f60ad1SHasso Tepper 				*cp++ = '\0';
24637f60ad1SHasso Tepper 		}
24737f60ad1SHasso Tepper 	}
24837f60ad1SHasso Tepper 	*q = NULL;
24937f60ad1SHasso Tepper 
25037f60ad1SHasso Tepper 	return (&proto);
25137f60ad1SHasso Tepper }
25237f60ad1SHasso Tepper 
25337f60ad1SHasso Tepper void
bt_setprotoent(int stayopen)25437f60ad1SHasso Tepper bt_setprotoent(int stayopen)
25537f60ad1SHasso Tepper {
25637f60ad1SHasso Tepper 	if (protof == NULL)
25737f60ad1SHasso Tepper 		protof = fopen(_PATH_BT_PROTOCOLS, "r");
25837f60ad1SHasso Tepper 	else
25937f60ad1SHasso Tepper 		rewind(protof);
26037f60ad1SHasso Tepper 
26137f60ad1SHasso Tepper 	proto_stayopen = stayopen;
26237f60ad1SHasso Tepper }
26337f60ad1SHasso Tepper 
26437f60ad1SHasso Tepper void
bt_endprotoent(void)26537f60ad1SHasso Tepper bt_endprotoent(void)
26637f60ad1SHasso Tepper {
26737f60ad1SHasso Tepper 	if (protof != NULL) {
26837f60ad1SHasso Tepper 		(void) fclose(protof);
26937f60ad1SHasso Tepper 		protof = NULL;
27037f60ad1SHasso Tepper 	}
27137f60ad1SHasso Tepper }
27237f60ad1SHasso Tepper 
27337f60ad1SHasso Tepper char const *
bt_ntoa(bdaddr_t const * ba,char * str)27437f60ad1SHasso Tepper bt_ntoa(bdaddr_t const *ba, char *str)
27537f60ad1SHasso Tepper {
27637f60ad1SHasso Tepper 	static char	buffer[24];
27737f60ad1SHasso Tepper 
27837f60ad1SHasso Tepper 	if (str == NULL)
27937f60ad1SHasso Tepper 		str = buffer;
28037f60ad1SHasso Tepper 
28137f60ad1SHasso Tepper 	sprintf(str, "%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x",
28237f60ad1SHasso Tepper 		ba->b[5], ba->b[4], ba->b[3], ba->b[2], ba->b[1], ba->b[0]);
28337f60ad1SHasso Tepper 
28437f60ad1SHasso Tepper 	return (str);
28537f60ad1SHasso Tepper }
28637f60ad1SHasso Tepper 
28737f60ad1SHasso Tepper int
bt_aton(char const * str,bdaddr_t * ba)28837f60ad1SHasso Tepper bt_aton(char const *str, bdaddr_t *ba)
28937f60ad1SHasso Tepper {
29037f60ad1SHasso Tepper 	int	 i, b;
29137f60ad1SHasso Tepper 	char	*end = NULL;
29237f60ad1SHasso Tepper 
29337f60ad1SHasso Tepper 	memset(ba, 0, sizeof(*ba));
29437f60ad1SHasso Tepper 
29537f60ad1SHasso Tepper 	for (i = 5, end = strchr(str, ':');
29637f60ad1SHasso Tepper 	     i > 0 && *str != '\0' && end != NULL;
29737f60ad1SHasso Tepper 	     i --, str = end + 1, end = strchr(str, ':')) {
29837f60ad1SHasso Tepper 		switch (end - str) {
29937f60ad1SHasso Tepper 		case 1:
30037f60ad1SHasso Tepper 			b = bt_hex_nibble(str[0]);
30137f60ad1SHasso Tepper 			break;
30237f60ad1SHasso Tepper 
30337f60ad1SHasso Tepper 		case 2:
30437f60ad1SHasso Tepper 			b = bt_hex_byte(str);
30537f60ad1SHasso Tepper 			break;
30637f60ad1SHasso Tepper 
30737f60ad1SHasso Tepper 		default:
30837f60ad1SHasso Tepper 			b = -1;
30937f60ad1SHasso Tepper 			break;
31037f60ad1SHasso Tepper 		}
31137f60ad1SHasso Tepper 
31237f60ad1SHasso Tepper 		if (b < 0)
31337f60ad1SHasso Tepper 			return (0);
31437f60ad1SHasso Tepper 
31537f60ad1SHasso Tepper 		ba->b[i] = b;
31637f60ad1SHasso Tepper 	}
31737f60ad1SHasso Tepper 
31837f60ad1SHasso Tepper 	if (i != 0 || end != NULL || *str == 0)
31937f60ad1SHasso Tepper 		return (0);
32037f60ad1SHasso Tepper 
32137f60ad1SHasso Tepper 	switch (strlen(str)) {
32237f60ad1SHasso Tepper 	case 1:
32337f60ad1SHasso Tepper 		b = bt_hex_nibble(str[0]);
32437f60ad1SHasso Tepper 		break;
32537f60ad1SHasso Tepper 
32637f60ad1SHasso Tepper 	case 2:
32737f60ad1SHasso Tepper 		b = bt_hex_byte(str);
32837f60ad1SHasso Tepper 		break;
32937f60ad1SHasso Tepper 
33037f60ad1SHasso Tepper 	default:
33137f60ad1SHasso Tepper 		b = -1;
33237f60ad1SHasso Tepper 		break;
33337f60ad1SHasso Tepper 	}
33437f60ad1SHasso Tepper 
33537f60ad1SHasso Tepper 	if (b < 0)
33637f60ad1SHasso Tepper 		return (0);
33737f60ad1SHasso Tepper 
33837f60ad1SHasso Tepper 	ba->b[i] = b;
33937f60ad1SHasso Tepper 
34037f60ad1SHasso Tepper 	return (1);
34137f60ad1SHasso Tepper }
34237f60ad1SHasso Tepper 
34337f60ad1SHasso Tepper static int
bt_hex_byte(char const * str)34437f60ad1SHasso Tepper bt_hex_byte(char const *str)
34537f60ad1SHasso Tepper {
34637f60ad1SHasso Tepper 	int	n1, n2;
34737f60ad1SHasso Tepper 
34837f60ad1SHasso Tepper 	if ((n1 = bt_hex_nibble(str[0])) < 0)
34937f60ad1SHasso Tepper 		return (-1);
35037f60ad1SHasso Tepper 
35137f60ad1SHasso Tepper 	if ((n2 = bt_hex_nibble(str[1])) < 0)
35237f60ad1SHasso Tepper 		return (-1);
35337f60ad1SHasso Tepper 
35437f60ad1SHasso Tepper 	return ((((n1 & 0x0f) << 4) | (n2 & 0x0f)) & 0xff);
35537f60ad1SHasso Tepper }
35637f60ad1SHasso Tepper 
35737f60ad1SHasso Tepper static int
bt_hex_nibble(char nibble)35837f60ad1SHasso Tepper bt_hex_nibble(char nibble)
35937f60ad1SHasso Tepper {
36037f60ad1SHasso Tepper 	if ('0' <= nibble && nibble <= '9')
36137f60ad1SHasso Tepper 		return (nibble - '0');
36237f60ad1SHasso Tepper 
36337f60ad1SHasso Tepper 	if ('a' <= nibble && nibble <= 'f')
36437f60ad1SHasso Tepper 		return (nibble - 'a' + 0xa);
36537f60ad1SHasso Tepper 
36637f60ad1SHasso Tepper 	if ('A' <= nibble && nibble <= 'F')
36737f60ad1SHasso Tepper 		return (nibble - 'A' + 0xa);
36837f60ad1SHasso Tepper 
36937f60ad1SHasso Tepper 	return (-1);
37037f60ad1SHasso Tepper }
371