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);
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;
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';
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);
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++))
int io_addr_get_domain(const io_addr_t *addr)
Obtains the domain of a network address.
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.
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.
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.
int io_addr_is_broadcast(const io_addr_t *addr)
Returns 1 if the network address is a broadcast address, and 0 if not.
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.
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.
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.
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...
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_is_multicast(const io_addr_t *addr)
Returns 1 if the network address is a multicast address, and 0 if not.
int io_addr_cmp(const void *p1, const void *p2)
Compares two network addresses.
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.
int io_addr_get_port(const io_addr_t *addr, int *port)
Obtains the port number of an IPv4 or IPv6 network address.
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.
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.
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.
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.
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.
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.
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.
int io_addr_is_loopback(const io_addr_t *addr)
Returns 1 if the network address is a loopback address, and 0 if not.
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_unix(const io_addr_t *addr, char *path)
Obtains a UNIX domain socket path name from a network address.
void io_addr_set_unix(io_addr_t *addr, const char *path)
Initializes a network address from a UNIX domain socket path name.
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 I/O library; it contains the network address declarations.
#define IO_ADDR_IPV6_STRLEN
The maximum number of bytes required to hold the text representation of an IPv6 internet address,...
#define IO_ADDR_IPV4_STRLEN
The maximum number of bytes required to hold the text representation of an IPv4 internet address,...
#define IO_ADDR_UNIX_STRLEN
The maximum number of bytes required to hold the text representation of a UNIX domain socket path nam...
This header file is part of the utilities library; it contains the comparison function definitions.
This header file is part of the utilities library; it contains the native and platform-independent er...
@ ERRNUM_AI_MEMORY
There was a memory allocation failure.
@ ERRNUM_AFNOSUPPORT
Address family not supported.
@ ERRNUM_AI_BADFLAGS
The flags had an invalid value.
@ ERRNUM_AI_SOCKTYPE
The intended socket type was not recognized.
@ ERRNUM_INVAL
Invalid argument.
@ ERRNUM_AI_AGAIN
The name could not be resolved at this time.
@ ERRNUM_AI_FAIL
A non-recoverable error occurred.
@ ERRNUM_AI_FAMILY
The address family was not recognized or the address length was invalid for the specified family.
@ ERRNUM_AI_SERVICE
The service passed was not recognized for the specified socket type.
@ ERRNUM_AI_NONAME
The name does not resolve for the supplied parameters.
void set_errnum(errnum_t errnum)
Sets the current (thread-specific) platform-independent error number to errnum.
#define MIN(a, b)
Returns the minimum of a and b.
This header file is part of the I/O library; it contains the network socket declarations.
@ IO_SOCK_DGRAM
A datagram-oriented, typically connectionless-mode, socket type.
@ IO_SOCK_STREAM
A stream-oriented connection-mode socket type.
@ IO_SOCK_IPV4
An IPv4 socket.
@ IO_SOCK_UNIX
A UNIX domain socket (only supported on POSIX platforms).
@ IO_SOCK_IPV6
An IPv6 socket.
@ IO_SOCK_BTH
A Bluetooth socket.
This is the internal header file of the Windows-specific I/O declarations.
This header file is part of the C11 and POSIX compatibility library; it includes <stdio....
This header file is part of the C11 and POSIX compatibility library; it includes <stdlib....
This header file is part of the C11 and POSIX compatibility library; it includes <string....
An opaque network address type.
union __io_addr::@5 addr
The network address.
int addrlen
The size (in bytes) of addr.
A network address info structure.
int type
The type of the socket (either IO_SOCK_STREAM or IO_SOCK_DGRAM).
int domain
The domain of the socket (only IO_SOCK_IPV4 and IO_SOCK_IPV6 are supported).
io_addr_t addr
The network address.