39 static int ba2str(
const BTH_ADDR *ba,
char *str);
40 static int str2ba(
const char *str, BTH_ADDR *ba);
41 static int bachk(
const char *str);
43 #elif _POSIX_C_SOURCE >= 200112L
68 #if defined(_WIN32) || (defined(__linux__) \
69 && defined(HAVE_BLUETOOTH_BLUETOOTH_H) \
70 && defined(HAVE_BLUETOOTH_RFCOMM_H))
79 if (addr->
addrlen < (
int)
sizeof(SOCKADDR_BTH)) {
80 WSASetLastError(WSAEINVAL);
84 const SOCKADDR_BTH *addr_bth = (
const SOCKADDR_BTH *)&addr->
addr;
85 if (addr_bth->addressFamily != AF_BTH) {
86 WSASetLastError(WSAEAFNOSUPPORT);
91 *port = addr_bth->port == BT_PORT_ANY ? 0 : addr_bth->port;
92 if (ba && ba2str(&addr_bth->btAddr, ba) < 0)
95 if (addr->
addrlen < (
int)
sizeof(
struct sockaddr_rc)) {
100 const struct sockaddr_rc *addr_rc =
101 (
const struct sockaddr_rc *)&addr->
addr;
102 if (addr_rc->rc_family != AF_BLUETOOTH) {
103 errno = EAFNOSUPPORT;
108 *port = btohs(addr_rc->rc_channel);
109 if (ba && ba2str(&addr_rc->rc_bdaddr, ba) < 0)
121 memset(addr, 0,
sizeof(*addr));
123 addr->
addrlen =
sizeof(SOCKADDR_BTH);
124 SOCKADDR_BTH *addr_bth = (SOCKADDR_BTH *)&addr->
addr;
126 addr_bth->addressFamily = AF_BTH;
127 addr_bth->port = port ? (ULONG)port : BT_PORT_ANY;
128 addr_bth->btAddr = 0;
130 if (str2ba(ba, &addr_bth->btAddr) < 0)
134 addr->
addrlen =
sizeof(
struct sockaddr_rc);
135 struct sockaddr_rc *addr_rc = (
struct sockaddr_rc *)&addr->
addr;
137 addr_rc->rc_family = AF_BLUETOOTH;
138 addr_rc->rc_channel = htobs(port);
140 if (str2ba(ba, &addr_rc->rc_bdaddr) < 0)
143 bacpy(&addr_rc->rc_bdaddr, BDADDR_ANY);
156 if (addr->
addrlen < (
int)
sizeof(SOCKADDR_BTH)) {
157 WSASetLastError(WSAEINVAL);
161 const SOCKADDR_BTH *addr_bth = (
const SOCKADDR_BTH *)&addr->
addr;
162 if (addr_bth->addressFamily != AF_BTH) {
163 WSASetLastError(WSAEAFNOSUPPORT);
168 *port = addr_bth->port == BT_PORT_ANY ? 0 : addr_bth->port;
170 for (
int i = 0; i < 6; i++)
171 ba[i] = (addr_bth->btAddr >> (7 - i) * 8) & 0xff;
174 if (addr->
addrlen < (
int)
sizeof(
struct sockaddr_rc)) {
179 const struct sockaddr_rc *addr_rc =
180 (
const struct sockaddr_rc *)&addr->
addr;
181 if (addr_rc->rc_family != AF_BLUETOOTH) {
182 errno = EAFNOSUPPORT;
187 *port = btohs(addr_rc->rc_channel);
189 memcpy(ba, &addr_rc->rc_bdaddr, 6);
200 memset(addr, 0,
sizeof(*addr));
202 addr->
addrlen =
sizeof(SOCKADDR_BTH);
203 SOCKADDR_BTH *addr_bth = (SOCKADDR_BTH *)&addr->
addr;
205 addr_bth->addressFamily = AF_BTH;
206 addr_bth->port = port ? (ULONG)port : BT_PORT_ANY;
207 addr_bth->btAddr = 0;
209 for (
int i = 0; i < 6; i++)
210 addr_bth->btAddr |= (BTH_ADDR)ba[i] << (7 - i) * 8;
213 addr->
addrlen =
sizeof(
struct sockaddr_rc);
214 struct sockaddr_rc *addr_rc = (
struct sockaddr_rc *)&addr->
addr;
216 addr_rc->rc_family = AF_BLUETOOTH;
217 addr_rc->rc_channel = htobs(port);
219 memcpy(&addr_rc->rc_bdaddr, ba, 6);
221 bacpy(&addr_rc->rc_bdaddr, BDADDR_ANY);
230 memset(addr, 0,
sizeof(*addr));
232 addr->
addrlen =
sizeof(SOCKADDR_BTH);
233 SOCKADDR_BTH *addr_bth = (SOCKADDR_BTH *)&addr->
addr;
235 addr_bth->addressFamily = AF_BTH;
236 addr_bth->port = port ? (ULONG)port : BT_PORT_ANY;
237 addr_bth->btAddr = (BTH_ADDR)0xffffff000000ull;
239 addr->
addrlen =
sizeof(
struct sockaddr_rc);
240 struct sockaddr_rc *addr_rc = (
struct sockaddr_rc *)&addr->
addr;
242 addr_rc->rc_family = AF_BLUETOOTH;
243 addr_rc->rc_channel = htobs(port);
244 bacpy(&addr_rc->rc_bdaddr, BDADDR_LOCAL);
249 #endif // _WIN32 || (__linux__ && HAVE_BLUETOOTH_BLUETOOTH_H && HAVE_BLUETOOTH_RFCOMM_H)
252 #if defined(_WIN32) || _POSIX_C_SOURCE >= 200112L
259 if (addr->
addrlen < (
int)
sizeof(
struct sockaddr_in)) {
264 const struct sockaddr_in *addr_in =
265 (
const struct sockaddr_in *)&addr->
addr;
266 if (addr_in->sin_family != AF_INET) {
272 *port = ntohs(addr_in->sin_port);
274 if (ip && !inet_ntop(AF_INET, (
void *)&addr_in->sin_addr, ip,
287 memset(addr, 0,
sizeof(*addr));
288 addr->
addrlen =
sizeof(
struct sockaddr_in);
289 struct sockaddr_in *addr_in = (
struct sockaddr_in *)&addr->
addr;
291 addr_in->sin_family = AF_INET;
292 addr_in->sin_port = htons(port);
294 if (inet_pton(AF_INET, ip, &addr_in->sin_addr) != 1)
297 addr_in->sin_addr.s_addr = htonl(INADDR_ANY);
308 if (addr->
addrlen < (
int)
sizeof(
struct sockaddr_in)) {
313 const struct sockaddr_in *addr_in =
314 (
const struct sockaddr_in *)&addr->
addr;
315 if (addr_in->sin_family != AF_INET) {
321 *port = ntohs(addr_in->sin_port);
323 memcpy(ip, &addr_in->sin_addr.s_addr, 4);
333 memset(addr, 0,
sizeof(*addr));
334 addr->
addrlen =
sizeof(
struct sockaddr_in);
335 struct sockaddr_in *addr_in = (
struct sockaddr_in *)&addr->
addr;
337 addr_in->sin_family = AF_INET;
338 addr_in->sin_port = htons(port);
340 memcpy(&addr_in->sin_addr.s_addr, ip, 4);
342 addr_in->sin_addr.s_addr = htonl(INADDR_ANY);
350 memset(addr, 0,
sizeof(*addr));
351 addr->
addrlen =
sizeof(
struct sockaddr_in);
352 struct sockaddr_in *addr_in = (
struct sockaddr_in *)&addr->
addr;
354 addr_in->sin_family = AF_INET;
355 addr_in->sin_port = htons(port);
356 addr_in->sin_addr.s_addr = htonl(INADDR_LOOPBACK);
364 memset(addr, 0,
sizeof(*addr));
365 addr->
addrlen =
sizeof(
struct sockaddr_in);
366 struct sockaddr_in *addr_in = (
struct sockaddr_in *)&addr->
addr;
368 addr_in->sin_family = AF_INET;
369 addr_in->sin_port = htons(port);
370 addr_in->sin_addr.s_addr = htonl(INADDR_BROADCAST);
378 if (addr->
addrlen < (
int)
sizeof(
struct sockaddr_in6)) {
383 const struct sockaddr_in6 *addr_in6 =
384 (
const struct sockaddr_in6 *)&addr->
addr;
385 if (addr_in6->sin6_family != AF_INET6) {
391 *port = ntohs(addr_in6->sin6_port);
393 if (ip && !inet_ntop(AF_INET6, (
void *)&addr_in6->sin6_addr, ip,
406 memset(addr, 0,
sizeof(*addr));
407 addr->
addrlen =
sizeof(
struct sockaddr_in6);
408 struct sockaddr_in6 *addr_in6 = (
struct sockaddr_in6 *)&addr->
addr;
410 addr_in6->sin6_family = AF_INET6;
411 addr_in6->sin6_port = htons(port);
413 if (inet_pton(AF_INET6, ip, &addr_in6->sin6_addr) != 1)
416 addr_in6->sin6_addr = in6addr_any;
427 if (addr->
addrlen < (
int)
sizeof(
struct sockaddr_in6)) {
432 const struct sockaddr_in6 *addr_in6 =
433 (
const struct sockaddr_in6 *)&addr->
addr;
434 if (addr_in6->sin6_family != AF_INET6) {
440 *port = ntohs(addr_in6->sin6_port);
442 memcpy(ip, &addr_in6->sin6_addr.s6_addr, 16);
452 memset(addr, 0,
sizeof(*addr));
453 addr->
addrlen =
sizeof(
struct sockaddr_in6);
454 struct sockaddr_in6 *addr_in6 = (
struct sockaddr_in6 *)&addr->
addr;
456 addr_in6->sin6_family = AF_INET6;
457 addr_in6->sin6_port = htons(port);
459 memcpy(&addr_in6->sin6_addr.s6_addr, ip, 16);
461 addr_in6->sin6_addr = in6addr_any;
469 memset(addr, 0,
sizeof(*addr));
470 addr->
addrlen =
sizeof(
struct sockaddr_in6);
471 struct sockaddr_in6 *addr_in6 = (
struct sockaddr_in6 *)&addr->
addr;
473 addr_in6->sin6_family = AF_INET6;
474 addr_in6->sin6_port = htons(port);
475 addr_in6->sin6_addr = in6addr_loopback;
478 #endif // _WIN32 || _POSIX_C_SOURCE >= 200112L
480 #if _POSIX_C_SOURCE >= 200112L
487 if (addr->
addrlen < (
int)
sizeof(
struct sockaddr_un)) {
492 const struct sockaddr_un *addr_un =
493 (
const struct sockaddr_un *)&addr->
addr;
494 if (addr_un->sun_family != AF_UNIX) {
495 errno = EAFNOSUPPORT;
511 memset(addr, 0,
sizeof(*addr));
512 addr->
addrlen =
sizeof(
struct sockaddr_un);
513 struct sockaddr_un *addr_un = (
struct sockaddr_un *)&addr->
addr;
515 addr_un->sun_family = AF_UNIX;
517 size_t n =
MIN(strlen(path),
sizeof(addr_un->sun_path) - 1);
518 strncpy(addr_un->sun_path, path, n);
519 addr_un->sun_path[n] =
'\0';
522 #endif // _POSIX_C_SOURCE >= 200112L
524 #if defined(_WIN32) || _POSIX_C_SOURCE >= 200112L
531 switch (((
const struct sockaddr *)&addr->
addr)->sa_family) {
534 #elif defined(__linux__) && defined(HAVE_BLUETOOTH_BLUETOOTH_H) \
535 && defined(HAVE_BLUETOOTH_RFCOMM_H)
540 #if _POSIX_C_SOURCE >= 200112L
552 if (addr->
addrlen < (
int)
sizeof(sa_family_t)) {
557 switch (((
const struct sockaddr *)&addr->
addr)->sa_family) {
560 if (addr->
addrlen < (
int)
sizeof(SOCKADDR_BTH)) {
561 WSASetLastError(WSAEINVAL);
564 const SOCKADDR_BTH *addr_bth =
565 (
const SOCKADDR_BTH *)&addr->
addr;
568 *port = addr_bth->port == BT_PORT_ANY
569 ? 0 : addr_bth->port;
573 #elif defined(__linux__) && defined(HAVE_BLUETOOTH_BLUETOOTH_H) \
574 && defined(HAVE_BLUETOOTH_RFCOMM_H)
576 if (addr->
addrlen < (
int)
sizeof(
struct sockaddr_rc)) {
580 const struct sockaddr_rc *addr_rc =
581 (
const struct sockaddr_rc *)&addr->
addr;
583 *port = btohs(addr_rc->rc_channel);
588 if (addr->
addrlen < (
int)
sizeof(
struct sockaddr_in)) {
592 const struct sockaddr_in *addr_in =
593 (
const struct sockaddr_in *)&addr->
addr;
595 *port = ntohs(addr_in->sin_port);
599 if (addr->
addrlen < (
int)
sizeof(
struct sockaddr_in6)) {
603 const struct sockaddr_in6 *addr_in6 =
604 (
const struct sockaddr_in6 *)&addr->
addr;
606 *port = ntohs(addr_in6->sin6_port);
618 if (addr->
addrlen < (
int)
sizeof(sa_family_t)) {
623 switch (((
struct sockaddr *)&addr->
addr)->sa_family) {
626 if (addr->
addrlen < (
int)
sizeof(SOCKADDR_BTH)) {
627 WSASetLastError(WSAEINVAL);
630 ((SOCKADDR_BTH *)&addr->
addr)->port =
631 port ? (ULONG)port : BT_PORT_ANY;
634 #elif defined(__linux__) && defined(HAVE_BLUETOOTH_BLUETOOTH_H) \
635 && defined(HAVE_BLUETOOTH_RFCOMM_H)
637 if (addr->
addrlen < (
int)
sizeof(
struct sockaddr_rc)) {
641 ((
struct sockaddr_rc *)&addr->
addr)->rc_channel = htobs(port);
645 if (addr->
addrlen < (
int)
sizeof(
struct sockaddr_in)) {
649 ((
struct sockaddr_in *)&addr->
addr)->sin_port = htons(port);
652 if (addr->
addrlen < (
int)
sizeof(
struct sockaddr_in6)) {
656 ((
struct sockaddr_in6 *)&addr->
addr)->sin6_port = htons(port);
667 if (addr->
addrlen < (
int)
sizeof(sa_family_t))
670 switch (((
const struct sockaddr *)&addr->
addr)->sa_family) {
672 if (addr->
addrlen < (
int)
sizeof(
struct sockaddr_in))
674 const struct sockaddr_in *addr_in =
675 (
const struct sockaddr_in *)&addr->
addr;
676 return ntohl(addr_in->sin_addr.s_addr) == INADDR_LOOPBACK;
679 if (addr->
addrlen < (
int)
sizeof(
struct sockaddr_in6))
681 const struct sockaddr_in6 *addr_in6 =
682 (
const struct sockaddr_in6 *)&addr->
addr;
683 return !memcmp(&addr_in6->sin6_addr, &in6addr_any,
684 sizeof(in6addr_any));
695 if (addr->
addrlen < (
int)
sizeof(sa_family_t))
698 switch (((
const struct sockaddr *)&addr->
addr)->sa_family) {
700 if (addr->
addrlen < (
int)
sizeof(
struct sockaddr_in))
702 const struct sockaddr_in *addr_in =
703 (
const struct sockaddr_in *)&addr->
addr;
704 return ntohl(addr_in->sin_addr.s_addr) == INADDR_BROADCAST;
715 if (addr->
addrlen < (
int)
sizeof(sa_family_t))
718 switch (((
const struct sockaddr *)&addr->
addr)->sa_family) {
720 if (addr->
addrlen < (
int)
sizeof(
struct sockaddr_in))
722 const struct sockaddr_in *addr_in =
723 (
const struct sockaddr_in *)&addr->
addr;
724 return (ntohl(addr_in->sin_addr.s_addr) >> 28) == 0xe;
727 if (addr->
addrlen < (
int)
sizeof(
struct sockaddr_in6))
729 const struct sockaddr_in6 *addr_in6 =
730 (
const struct sockaddr_in6 *)&addr->
addr;
731 return addr_in6->sin6_addr.s6_addr[0] == 0xff;
739 const char *servname,
const struct io_addrinfo *hints)
746 struct addrinfo ai_hints = { .ai_family = AF_UNSPEC };
751 case IO_SOCK_IPV6: ai_hints.ai_family = AF_INET6;
break;
752 default: ecode = EAI_FAMILY;
break;
755 switch (hints->
type) {
758 case IO_SOCK_DGRAM: ai_hints.ai_socktype = SOCK_DGRAM;
break;
759 default: ecode = EAI_SOCKTYPE;
break;
763 struct addrinfo *res = NULL;
765 ecode = getaddrinfo(nodename, servname, &ai_hints, &res);
777 case EAI_SYSTEM:
break;
785 for (
struct addrinfo *ai = res; ai; ai = ai->ai_next) {
787 switch (ai->ai_family) {
794 switch (ai->ai_socktype) {
800 if (ninfo++ < maxinfo) {
801 memset(info, 0,
sizeof(*info));
805 memcpy(&info->
addr.
addr, ai->ai_addr, ai->ai_addrlen);
815 #endif // _WIN32 || _POSIX_C_SOURCE >= 200112L
820 ba2str(
const BTH_ADDR *ba,
char *str)
822 return sprintf(str,
"%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X",
823 (
int)((*ba >> 40) & 0xff), (
int)((*ba >> 32) & 0xff),
824 (
int)((*ba >> 24) & 0xff), (
int)((*ba >> 16) & 0xff),
825 ((
int)(*ba >> 8) & 0xff), (
int)(*ba & 0xff));
829 str2ba(
const char *str, BTH_ADDR *ba)
831 if (bachk(str) < 0) {
836 for (
int i = 5; i >= 0; i--, str += 3)
837 *ba |= (BTH_ADDR)strtol(str, NULL, 16) << (i * 8);
843 bachk(
const char *str)
847 if (strlen(str) != 17)
851 if (!isxdigit(*str++))
853 if (!isxdigit(*str++))