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++))
int io_addr_is_multicast(const io_addr_t *addr)
Returns 1 if the network address is a multicast address, and 0 if not.
The intended socket type was not recognized.
void io_addr_set_ipv4_n(io_addr_t *addr, const uint8_t ip[4], int port)
Initializes a network address from an IPv4 address and port number.
int io_addr_get_ipv4_a(const io_addr_t *addr, char *ip, int *port)
Obtains an IPv4 address and port number from a network address.
This header file is part of the C11 and POSIX compatibility library; it includes <string.h> and defines any missing functionality.
void io_addr_set_unix(io_addr_t *addr, const char *path)
Initializes a network address from a UNIX domain socket path name.
This header file is part of the utilities library; it contains the comparison function definitions...
void io_addr_set_ipv4_broadcast(io_addr_t *addr, int port)
Initializes a network address with the IPv4 broadcast address and a port number.
A stream-oriented connection-mode socket type.
void set_errnum(errnum_t errnum)
Sets the current (thread-specific) platform-independent error number to errnum.
The address family was not recognized or the address length was invalid for the specified family...
int io_addr_is_loopback(const io_addr_t *addr)
Returns 1 if the network address is a loopback address, and 0 if not.
An opaque network address type.
void io_addr_set_ipv6_n(io_addr_t *addr, const uint8_t ip[16], int port)
Initializes a network address from an IPv6 address and port number.
#define MIN(a, b)
Returns the minimum of a and b.
A network address info structure.
union __io_addr::@5 addr
The network address.
#define IO_ADDR_UNIX_STRLEN
The maximum number of bytes required to hold the text representation of a UNIX domain socket path nam...
int io_get_addrinfo(int maxinfo, struct io_addrinfo *info, const char *nodename, const char *servname, const struct io_addrinfo *hints)
Obtains a list of network addresses corresponding to a host and/or service name.
A UNIX domain socket (only supported on POSIX platforms).
This header file is part of the utilities library; it contains the native and platform-independent er...
Address family not supported.
The flags had an invalid value.
int io_addr_is_broadcast(const io_addr_t *addr)
Returns 1 if the network address is a broadcast address, and 0 if not.
A non-recoverable error occurred.
int io_addr_get_unix(const io_addr_t *addr, char *path)
Obtains a UNIX domain socket path name from a network address.
#define IO_ADDR_IPV4_STRLEN
The maximum number of bytes required to hold the text representation of an IPv4 internet address...
void io_addr_set_rfcomm_n(io_addr_t *addr, const uint8_t ba[6], int port)
Initializes a network address from an RFCOMM Bluetooth device address and port number.
int addrlen
The size (in bytes) of addr.
int domain
The domain of the socket (only IO_SOCK_IPV4 and IO_SOCK_IPV6 are supported).
int io_addr_set_port(io_addr_t *addr, int port)
Initializes the port number of an IPv4 or IPv6 network address.
int io_addr_set_ipv4_a(io_addr_t *addr, const char *ip, int port)
Initializes a network address from an IPv4 address and port number.
int io_addr_get_domain(const io_addr_t *addr)
Obtains the domain of a network address.
This header file is part of the I/O library; it contains the network socket declarations.
int io_addr_get_ipv6_n(const io_addr_t *addr, uint8_t ip[16], int *port)
Obtains an IPv6 address and port number from a network address.
int io_addr_set_ipv6_a(io_addr_t *addr, const char *ip, int port)
Initializes a network address from an IPv6 address and port number.
A datagram-oriented, typically connectionless-mode, socket type.
int io_addr_get_rfcomm_a(const io_addr_t *addr, char *ba, int *port)
Obtains an RFCOMM Bluetooth device address and port number from a network address.
This is the internal header file of the I/O library.
int io_addr_set_rfcomm_a(io_addr_t *addr, const char *ba, int port)
Initializes a network address from an RFCOMM Bluetooth device address and port number.
#define IO_ADDR_IPV6_STRLEN
The maximum number of bytes required to hold the text representation of an IPv6 internet address...
int io_addr_get_ipv4_n(const io_addr_t *addr, uint8_t ip[4], int *port)
Obtains an IPv4 address and port number from a network address.
void io_addr_set_ipv4_loopback(io_addr_t *addr, int port)
Initializes a network address with the IPv4 loopback address and a port number.
This header file is part of the C11 and POSIX compatibility library; it includes <stdio.h> and defines any missing functionality.
int io_addr_get_ipv6_a(const io_addr_t *addr, char *ip, int *port)
Obtains an IPv6 address and port number from a network address.
io_addr_t addr
The network address.
This header file is part of the C11 and POSIX compatibility library; it includes <stdlib.h> and defines any missing functionality.
The service passed was not recognized for the specified socket type.
The name does not resolve for the supplied parameters.
int io_addr_get_rfcomm_n(const io_addr_t *addr, uint8_t ba[6], int *port)
Obtains an RFCOMM Bluetooth device address and port number from a network address.
The name could not be resolved at this time.
void io_addr_set_rfcomm_local(io_addr_t *addr, int port)
Initializes a network address with the local Bluetooth (RFCOMM) device address (FF:FF:FF:00:00:00) an...
void io_addr_set_ipv6_loopback(io_addr_t *addr, int port)
Initializes a network address with the IPv6 loopback address and a port number.
There was a memory allocation failure.
int type
The type of the socket (either IO_SOCK_STREAM or IO_SOCK_DGRAM).
int io_addr_get_port(const io_addr_t *addr, int *port)
Obtains the port number of an IPv4 or IPv6 network address.
This header file is part of the I/O library; it contains the network address declarations.
int io_addr_cmp(const void *p1, const void *p2)
Compares two network addresses.