42 static int ba2str(
const BTH_ADDR *ba,
char *str);
43 static int str2ba(
const char *str, BTH_ADDR *ba);
44 static int bachk(
const char *str);
46 #elif _POSIX_C_SOURCE >= 200112L
71 #if _WIN32 || (defined(__linux__) \
72 && defined(HAVE_BLUETOOTH_BLUETOOTH_H) \
73 && defined(HAVE_BLUETOOTH_RFCOMM_H))
82 if (addr->
addrlen < (
int)
sizeof(SOCKADDR_BTH)) {
83 WSASetLastError(WSAEINVAL);
87 const SOCKADDR_BTH *addr_bth = (
const SOCKADDR_BTH *)&addr->
addr;
88 if (addr_bth->addressFamily != AF_BTH) {
89 WSASetLastError(WSAEAFNOSUPPORT);
94 *port = addr_bth->port == BT_PORT_ANY ? 0 : addr_bth->port;
95 if (ba && ba2str(&addr_bth->btAddr, ba) < 0)
98 if (addr->
addrlen < (
int)
sizeof(
struct sockaddr_rc)) {
103 const struct sockaddr_rc *addr_rc =
104 (
const struct sockaddr_rc *)&addr->
addr;
105 if (addr_rc->rc_family != AF_BLUETOOTH) {
106 errno = EAFNOSUPPORT;
111 *port = btohs(addr_rc->rc_channel);
112 if (ba && ba2str(&addr_rc->rc_bdaddr, ba) < 0)
124 memset(addr, 0,
sizeof(*addr));
126 addr->
addrlen =
sizeof(SOCKADDR_BTH);
127 SOCKADDR_BTH *addr_bth = (SOCKADDR_BTH *)&addr->
addr;
129 addr_bth->addressFamily = AF_BTH;
130 addr_bth->port = port ? (ULONG)port : BT_PORT_ANY;
131 addr_bth->btAddr = 0;
133 if (str2ba(ba, &addr_bth->btAddr) < 0)
137 addr->
addrlen =
sizeof(
struct sockaddr_rc);
138 struct sockaddr_rc *addr_rc = (
struct sockaddr_rc *)&addr->
addr;
140 addr_rc->rc_family = AF_BLUETOOTH;
141 addr_rc->rc_channel = htobs(port);
143 if (str2ba(ba, &addr_rc->rc_bdaddr) < 0)
146 bacpy(&addr_rc->rc_bdaddr, BDADDR_ANY);
159 if (addr->
addrlen < (
int)
sizeof(SOCKADDR_BTH)) {
160 WSASetLastError(WSAEINVAL);
164 const SOCKADDR_BTH *addr_bth = (
const SOCKADDR_BTH *)&addr->
addr;
165 if (addr_bth->addressFamily != AF_BTH) {
166 WSASetLastError(WSAEAFNOSUPPORT);
171 *port = addr_bth->port == BT_PORT_ANY ? 0 : addr_bth->port;
173 for (
int i = 0; i < 6; i++)
174 ba[i] = (addr_bth->btAddr >> (7 - i) * 8) & 0xff;
177 if (addr->
addrlen < (
int)
sizeof(
struct sockaddr_rc)) {
182 const struct sockaddr_rc *addr_rc =
183 (
const struct sockaddr_rc *)&addr->
addr;
184 if (addr_rc->rc_family != AF_BLUETOOTH) {
185 errno = EAFNOSUPPORT;
190 *port = btohs(addr_rc->rc_channel);
192 memcpy(ba, &addr_rc->rc_bdaddr, 6);
203 memset(addr, 0,
sizeof(*addr));
205 addr->
addrlen =
sizeof(SOCKADDR_BTH);
206 SOCKADDR_BTH *addr_bth = (SOCKADDR_BTH *)&addr->
addr;
208 addr_bth->addressFamily = AF_BTH;
209 addr_bth->port = port ? (ULONG)port : BT_PORT_ANY;
210 addr_bth->btAddr = 0;
212 for (
int i = 0; i < 6; i++)
213 addr_bth->btAddr |= (BTH_ADDR)ba[i] << (7 - i) * 8;
216 addr->
addrlen =
sizeof(
struct sockaddr_rc);
217 struct sockaddr_rc *addr_rc = (
struct sockaddr_rc *)&addr->
addr;
219 addr_rc->rc_family = AF_BLUETOOTH;
220 addr_rc->rc_channel = htobs(port);
222 memcpy(&addr_rc->rc_bdaddr, ba, 6);
224 bacpy(&addr_rc->rc_bdaddr, BDADDR_ANY);
233 memset(addr, 0,
sizeof(*addr));
235 addr->
addrlen =
sizeof(SOCKADDR_BTH);
236 SOCKADDR_BTH *addr_bth = (SOCKADDR_BTH *)&addr->
addr;
238 addr_bth->addressFamily = AF_BTH;
239 addr_bth->port = port ? (ULONG)port : BT_PORT_ANY;
240 addr_bth->btAddr = (BTH_ADDR)0xffffff000000ull;
242 addr->
addrlen =
sizeof(
struct sockaddr_rc);
243 struct sockaddr_rc *addr_rc = (
struct sockaddr_rc *)&addr->
addr;
245 addr_rc->rc_family = AF_BLUETOOTH;
246 addr_rc->rc_channel = htobs(port);
247 bacpy(&addr_rc->rc_bdaddr, BDADDR_LOCAL);
252 #endif // _WIN32 || (__linux__ && HAVE_BLUETOOTH_BLUETOOTH_H && HAVE_BLUETOOTH_RFCOMM_H)
255 #if _WIN32 || _POSIX_C_SOURCE >= 200112L
262 if (addr->
addrlen < (
int)
sizeof(
struct sockaddr_in)) {
267 const struct sockaddr_in *addr_in =
268 (
const struct sockaddr_in *)&addr->
addr;
269 if (addr_in->sin_family != AF_INET) {
275 *port = ntohs(addr_in->sin_port);
277 if (ip && !inet_ntop(AF_INET, (
void *)&addr_in->sin_addr, ip,
290 memset(addr, 0,
sizeof(*addr));
291 addr->
addrlen =
sizeof(
struct sockaddr_in);
292 struct sockaddr_in *addr_in = (
struct sockaddr_in *)&addr->
addr;
294 addr_in->sin_family = AF_INET;
295 addr_in->sin_port = htons(port);
297 if (inet_pton(AF_INET, ip, &addr_in->sin_addr) != 1)
300 addr_in->sin_addr.s_addr = htonl(INADDR_ANY);
311 if (addr->
addrlen < (
int)
sizeof(
struct sockaddr_in)) {
316 const struct sockaddr_in *addr_in =
317 (
const struct sockaddr_in *)&addr->
addr;
318 if (addr_in->sin_family != AF_INET) {
324 *port = ntohs(addr_in->sin_port);
326 memcpy(ip, &addr_in->sin_addr.s_addr, 4);
336 memset(addr, 0,
sizeof(*addr));
337 addr->
addrlen =
sizeof(
struct sockaddr_in);
338 struct sockaddr_in *addr_in = (
struct sockaddr_in *)&addr->
addr;
340 addr_in->sin_family = AF_INET;
341 addr_in->sin_port = htons(port);
343 memcpy(&addr_in->sin_addr.s_addr, ip, 4);
345 addr_in->sin_addr.s_addr = htonl(INADDR_ANY);
353 memset(addr, 0,
sizeof(*addr));
354 addr->
addrlen =
sizeof(
struct sockaddr_in);
355 struct sockaddr_in *addr_in = (
struct sockaddr_in *)&addr->
addr;
357 addr_in->sin_family = AF_INET;
358 addr_in->sin_port = htons(port);
359 addr_in->sin_addr.s_addr = htonl(INADDR_LOOPBACK);
367 memset(addr, 0,
sizeof(*addr));
368 addr->
addrlen =
sizeof(
struct sockaddr_in);
369 struct sockaddr_in *addr_in = (
struct sockaddr_in *)&addr->
addr;
371 addr_in->sin_family = AF_INET;
372 addr_in->sin_port = htons(port);
373 addr_in->sin_addr.s_addr = htonl(INADDR_BROADCAST);
381 if (addr->
addrlen < (
int)
sizeof(
struct sockaddr_in6)) {
386 const struct sockaddr_in6 *addr_in6 =
387 (
const struct sockaddr_in6 *)&addr->
addr;
388 if (addr_in6->sin6_family != AF_INET6) {
394 *port = ntohs(addr_in6->sin6_port);
396 if (ip && !inet_ntop(AF_INET6, (
void *)&addr_in6->sin6_addr, ip,
409 memset(addr, 0,
sizeof(*addr));
410 addr->
addrlen =
sizeof(
struct sockaddr_in6);
411 struct sockaddr_in6 *addr_in6 = (
struct sockaddr_in6 *)&addr->
addr;
413 addr_in6->sin6_family = AF_INET6;
414 addr_in6->sin6_port = htons(port);
416 if (inet_pton(AF_INET6, ip, &addr_in6->sin6_addr) != 1)
419 addr_in6->sin6_addr = in6addr_any;
430 if (addr->
addrlen < (
int)
sizeof(
struct sockaddr_in6)) {
435 const struct sockaddr_in6 *addr_in6 =
436 (
const struct sockaddr_in6 *)&addr->
addr;
437 if (addr_in6->sin6_family != AF_INET6) {
443 *port = ntohs(addr_in6->sin6_port);
445 memcpy(ip, &addr_in6->sin6_addr.s6_addr, 16);
455 memset(addr, 0,
sizeof(*addr));
456 addr->
addrlen =
sizeof(
struct sockaddr_in6);
457 struct sockaddr_in6 *addr_in6 = (
struct sockaddr_in6 *)&addr->
addr;
459 addr_in6->sin6_family = AF_INET6;
460 addr_in6->sin6_port = htons(port);
462 memcpy(&addr_in6->sin6_addr.s6_addr, ip, 16);
464 addr_in6->sin6_addr = in6addr_any;
472 memset(addr, 0,
sizeof(*addr));
473 addr->
addrlen =
sizeof(
struct sockaddr_in6);
474 struct sockaddr_in6 *addr_in6 = (
struct sockaddr_in6 *)&addr->
addr;
476 addr_in6->sin6_family = AF_INET6;
477 addr_in6->sin6_port = htons(port);
478 addr_in6->sin6_addr = in6addr_loopback;
481 #endif // _WIN32 || _POSIX_C_SOURCE >= 200112L
483 #if _POSIX_C_SOURCE >= 200112L
490 if (addr->
addrlen < (
int)
sizeof(
struct sockaddr_un)) {
495 const struct sockaddr_un *addr_un =
496 (
const struct sockaddr_un *)&addr->
addr;
497 if (addr_un->sun_family != AF_UNIX) {
498 errno = EAFNOSUPPORT;
514 memset(addr, 0,
sizeof(*addr));
515 addr->
addrlen =
sizeof(
struct sockaddr_un);
516 struct sockaddr_un *addr_un = (
struct sockaddr_un *)&addr->
addr;
518 addr_un->sun_family = AF_UNIX;
520 size_t n =
MIN(strlen(path),
sizeof(addr_un->sun_path) - 1);
521 memcpy(addr_un->sun_path, path, n);
522 addr_un->sun_path[n] =
'\0';
525 #endif // _POSIX_C_SOURCE >= 200112L
527 #if _WIN32 || _POSIX_C_SOURCE >= 200112L
534 switch (((
const struct sockaddr *)&addr->
addr)->sa_family) {
537 #elif defined(__linux__) && defined(HAVE_BLUETOOTH_BLUETOOTH_H) \
538 && defined(HAVE_BLUETOOTH_RFCOMM_H)
543 #if _POSIX_C_SOURCE >= 200112L
555 if (addr->
addrlen < (
int)
sizeof(sa_family_t)) {
560 switch (((
const struct sockaddr *)&addr->
addr)->sa_family) {
563 if (addr->
addrlen < (
int)
sizeof(SOCKADDR_BTH)) {
564 WSASetLastError(WSAEINVAL);
567 const SOCKADDR_BTH *addr_bth =
568 (
const SOCKADDR_BTH *)&addr->
addr;
571 *port = addr_bth->port == BT_PORT_ANY
572 ? 0 : addr_bth->port;
576 #elif defined(__linux__) && defined(HAVE_BLUETOOTH_BLUETOOTH_H) \
577 && defined(HAVE_BLUETOOTH_RFCOMM_H)
579 if (addr->
addrlen < (
int)
sizeof(
struct sockaddr_rc)) {
583 const struct sockaddr_rc *addr_rc =
584 (
const struct sockaddr_rc *)&addr->
addr;
586 *port = btohs(addr_rc->rc_channel);
591 if (addr->
addrlen < (
int)
sizeof(
struct sockaddr_in)) {
595 const struct sockaddr_in *addr_in =
596 (
const struct sockaddr_in *)&addr->
addr;
598 *port = ntohs(addr_in->sin_port);
602 if (addr->
addrlen < (
int)
sizeof(
struct sockaddr_in6)) {
606 const struct sockaddr_in6 *addr_in6 =
607 (
const struct sockaddr_in6 *)&addr->
addr;
609 *port = ntohs(addr_in6->sin6_port);
621 if (addr->
addrlen < (
int)
sizeof(sa_family_t)) {
626 switch (((
struct sockaddr *)&addr->
addr)->sa_family) {
629 if (addr->
addrlen < (
int)
sizeof(SOCKADDR_BTH)) {
630 WSASetLastError(WSAEINVAL);
633 ((SOCKADDR_BTH *)&addr->
addr)->port =
634 port ? (ULONG)port : BT_PORT_ANY;
637 #elif defined(__linux__) && defined(HAVE_BLUETOOTH_BLUETOOTH_H) \
638 && defined(HAVE_BLUETOOTH_RFCOMM_H)
640 if (addr->
addrlen < (
int)
sizeof(
struct sockaddr_rc)) {
644 ((
struct sockaddr_rc *)&addr->
addr)->rc_channel = htobs(port);
648 if (addr->
addrlen < (
int)
sizeof(
struct sockaddr_in)) {
652 ((
struct sockaddr_in *)&addr->
addr)->sin_port = htons(port);
655 if (addr->
addrlen < (
int)
sizeof(
struct sockaddr_in6)) {
659 ((
struct sockaddr_in6 *)&addr->
addr)->sin6_port = htons(port);
670 if (addr->
addrlen < (
int)
sizeof(sa_family_t))
673 switch (((
const struct sockaddr *)&addr->
addr)->sa_family) {
675 if (addr->
addrlen < (
int)
sizeof(
struct sockaddr_in))
677 const struct sockaddr_in *addr_in =
678 (
const struct sockaddr_in *)&addr->
addr;
679 return ntohl(addr_in->sin_addr.s_addr) == INADDR_LOOPBACK;
682 if (addr->
addrlen < (
int)
sizeof(
struct sockaddr_in6))
684 const struct sockaddr_in6 *addr_in6 =
685 (
const struct sockaddr_in6 *)&addr->
addr;
686 return !memcmp(&addr_in6->sin6_addr, &in6addr_any,
687 sizeof(in6addr_any));
698 if (addr->
addrlen < (
int)
sizeof(sa_family_t))
701 switch (((
const struct sockaddr *)&addr->
addr)->sa_family) {
703 if (addr->
addrlen < (
int)
sizeof(
struct sockaddr_in))
705 const struct sockaddr_in *addr_in =
706 (
const struct sockaddr_in *)&addr->
addr;
707 return ntohl(addr_in->sin_addr.s_addr) == INADDR_BROADCAST;
718 if (addr->
addrlen < (
int)
sizeof(sa_family_t))
721 switch (((
const struct sockaddr *)&addr->
addr)->sa_family) {
723 if (addr->
addrlen < (
int)
sizeof(
struct sockaddr_in))
725 const struct sockaddr_in *addr_in =
726 (
const struct sockaddr_in *)&addr->
addr;
727 return (ntohl(addr_in->sin_addr.s_addr) >> 28) == 0xe;
730 if (addr->
addrlen < (
int)
sizeof(
struct sockaddr_in6))
732 const struct sockaddr_in6 *addr_in6 =
733 (
const struct sockaddr_in6 *)&addr->
addr;
734 return addr_in6->sin6_addr.s6_addr[0] == 0xff;
742 const char *servname,
const struct io_addrinfo *hints)
749 struct addrinfo ai_hints = { .ai_family = AF_UNSPEC };
754 case IO_SOCK_IPV6: ai_hints.ai_family = AF_INET6;
break;
755 default: ecode = EAI_FAMILY;
break;
758 switch (hints->
type) {
761 case IO_SOCK_DGRAM: ai_hints.ai_socktype = SOCK_DGRAM;
break;
762 default: ecode = EAI_SOCKTYPE;
break;
766 struct addrinfo *res = NULL;
768 ecode = getaddrinfo(nodename, servname, &ai_hints, &res);
780 case EAI_SYSTEM:
break;
788 for (
struct addrinfo *ai = res; ai; ai = ai->ai_next) {
790 switch (ai->ai_family) {
797 switch (ai->ai_socktype) {
803 if (ninfo++ < maxinfo) {
804 memset(info, 0,
sizeof(*info));
808 memcpy(&info->
addr.
addr, ai->ai_addr, ai->ai_addrlen);
818 #endif // _WIN32 || _POSIX_C_SOURCE >= 200112L
823 ba2str(
const BTH_ADDR *ba,
char *str)
825 return sprintf(str,
"%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X",
826 (
int)((*ba >> 40) & 0xff), (
int)((*ba >> 32) & 0xff),
827 (
int)((*ba >> 24) & 0xff), (
int)((*ba >> 16) & 0xff),
828 ((
int)(*ba >> 8) & 0xff), (
int)(*ba & 0xff));
832 str2ba(
const char *str, BTH_ADDR *ba)
834 if (bachk(str) < 0) {
839 for (
int i = 5; i >= 0; i--, str += 3)
840 *ba |= (BTH_ADDR)strtol(str, NULL, 16) << (i * 8);
846 bachk(
const char *str)
850 if (strlen(str) != 17)
854 if (!isxdigit(*str++))
856 if (!isxdigit(*str++))
869 #endif // !LELY_NO_STDIO