Merge pull request #20 from k0ekk0ek/getifaddrs
Replace os_sockQueryInterfaces by os_getifaddrs
This commit is contained in:
commit
6e1df4c564
33 changed files with 1140 additions and 1166 deletions
|
@ -10,6 +10,7 @@
|
|||
# SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
|
||||
#
|
||||
PREPEND(srcs_ddsi "${CMAKE_CURRENT_LIST_DIR}/src"
|
||||
ddsi_eth.c
|
||||
ddsi_ser.c
|
||||
ddsi_ssl.c
|
||||
ddsi_tcp.c
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
enum ddsi_nearby_address_result ddsi_ipaddr_is_nearby_address (ddsi_tran_factory_t tran, const nn_locator_t *loc, size_t ninterf, const struct nn_interface interf[]);
|
||||
enum ddsi_locator_from_string_result ddsi_ipaddr_from_string (ddsi_tran_factory_t tran, nn_locator_t *loc, const char *str, int32_t kind);
|
||||
char *ddsi_ipaddr_to_string (ddsi_tran_factory_t tran, char *dst, size_t sizeof_dst, const nn_locator_t *loc, int with_port);
|
||||
void ddsi_ipaddr_to_loc (nn_locator_t *dst, const os_sockaddr_storage *src, int32_t kind);
|
||||
void ddsi_ipaddr_to_loc (nn_locator_t *dst, const os_sockaddr *src, int32_t kind);
|
||||
void ddsi_ipaddr_from_loc (os_sockaddr_storage *dst, const nn_locator_t *src);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -75,7 +75,7 @@ typedef enum ddsi_locator_from_string_result (*ddsi_locator_from_string_fn_t) (d
|
|||
|
||||
typedef char * (*ddsi_locator_to_string_fn_t) (ddsi_tran_factory_t tran, char *dst, size_t sizeof_dst, const nn_locator_t *loc, int with_port);
|
||||
|
||||
typedef int (*ddsi_enumerate_interfaces_fn_t) (ddsi_tran_factory_t tran, int max, struct os_ifAttributes_s *interfs);
|
||||
typedef int (*ddsi_enumerate_interfaces_fn_t) (ddsi_tran_factory_t tran, os_ifaddrs_t **interfs);
|
||||
|
||||
/* Data types */
|
||||
|
||||
|
@ -237,7 +237,7 @@ enum ddsi_locator_from_string_result ddsi_locator_from_string (nn_locator_t *loc
|
|||
char *ddsi_locator_to_string (char *dst, size_t sizeof_dst, const nn_locator_t *loc);
|
||||
char *ddsi_locator_to_string_no_port (char *dst, size_t sizeof_dst, const nn_locator_t *loc);
|
||||
|
||||
int ddsi_enumerate_interfaces (ddsi_tran_factory_t factory, int max, struct os_ifAttributes_s *interfs);
|
||||
int ddsi_enumerate_interfaces (ddsi_tran_factory_t factory, os_ifaddrs_t **interfs);
|
||||
|
||||
#define ddsi_listener_locator(s,l) (ddsi_tran_locator (&(s)->m_base,(l)))
|
||||
ddsi_tran_conn_t ddsi_listener_accept (ddsi_tran_listener_t listener);
|
||||
|
|
29
src/core/ddsi/src/ddsi_eth.c
Normal file
29
src/core/ddsi/src/ddsi_eth.c
Normal file
|
@ -0,0 +1,29 @@
|
|||
/*
|
||||
* Copyright(c) 2006 to 2018 ADLINK Technology Limited and others
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License v. 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
|
||||
* v. 1.0 which is available at
|
||||
* http://www.eclipse.org/org/documents/edl-v10.php.
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
|
||||
*/
|
||||
#include "ddsi_eth.h"
|
||||
|
||||
int ddsi_eth_enumerate_interfaces(ddsi_tran_factory_t fact, os_ifaddrs_t **ifs)
|
||||
{
|
||||
int afs[] = { AF_INET, OS_AF_NULL };
|
||||
|
||||
(void)fact;
|
||||
|
||||
#if OS_SOCKET_HAVE_IPV6
|
||||
if (config.transport_selector == TRANS_TCP6 ||
|
||||
config.transport_selector == TRANS_UDP6)
|
||||
{
|
||||
afs[0] = AF_INET6;
|
||||
}
|
||||
#endif /* OS_SOCKET_HAVE_IPV6 */
|
||||
|
||||
return -os_getifaddrs(ifs, afs);
|
||||
}
|
20
src/core/ddsi/src/ddsi_eth.h
Normal file
20
src/core/ddsi/src/ddsi_eth.h
Normal file
|
@ -0,0 +1,20 @@
|
|||
/*
|
||||
* Copyright(c) 2006 to 2018 ADLINK Technology Limited and others
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License v. 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
|
||||
* v. 1.0 which is available at
|
||||
* http://www.eclipse.org/org/documents/edl-v10.php.
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
|
||||
*/
|
||||
#ifndef DDSI_ETH_H
|
||||
#define DDSI_ETH_H
|
||||
|
||||
#include "ddsi/ddsi_tran.h"
|
||||
#include "os/os.h"
|
||||
|
||||
int ddsi_eth_enumerate_interfaces(ddsi_tran_factory_t fact, os_ifaddrs_t **ifs);
|
||||
|
||||
#endif /* DDSI_ETH_H */
|
|
@ -29,7 +29,7 @@ enum ddsi_nearby_address_result ddsi_ipaddr_is_nearby_address (ddsi_tran_factory
|
|||
ddsi_ipaddr_from_loc(&ownip, &gv.ownloc);
|
||||
if (os_sockaddrSameSubnet ((os_sockaddr *) &tmp, (os_sockaddr *) &iftmp, (os_sockaddr *) &nmtmp))
|
||||
{
|
||||
if (os_sockaddrIPAddressEqual ((os_sockaddr*) &iftmp, (os_sockaddr*) &ownip))
|
||||
if (os_sockaddr_compare((os_sockaddr *)&iftmp, (os_sockaddr *)&ownip) == 0)
|
||||
return DNAR_SAME;
|
||||
else
|
||||
return DNAR_LOCAL;
|
||||
|
@ -49,7 +49,7 @@ enum ddsi_locator_from_string_result ddsi_ipaddr_from_string (ddsi_tran_factory_
|
|||
return AFSR_INVALID;
|
||||
if ((ipv4 && tmpaddr.ss_family != AF_INET) || (!ipv4 && tmpaddr.ss_family != AF_INET6))
|
||||
return AFSR_MISMATCH;
|
||||
ddsi_ipaddr_to_loc (loc, &tmpaddr, kind);
|
||||
ddsi_ipaddr_to_loc (loc, (os_sockaddr *)&tmpaddr, kind);
|
||||
/* This is just an address, so there is no valid value for port, other than INVALID.
|
||||
Without a guarantee that tmpaddr has port 0, best is to set it explicitly here */
|
||||
loc->port = NN_LOCATOR_PORT_INVALID;
|
||||
|
@ -94,10 +94,10 @@ char *ddsi_ipaddr_to_string (ddsi_tran_factory_t tran, char *dst, size_t sizeof_
|
|||
return dst;
|
||||
}
|
||||
|
||||
void ddsi_ipaddr_to_loc (nn_locator_t *dst, const os_sockaddr_storage *src, int32_t kind)
|
||||
void ddsi_ipaddr_to_loc (nn_locator_t *dst, const os_sockaddr *src, int32_t kind)
|
||||
{
|
||||
dst->kind = kind;
|
||||
switch (src->ss_family)
|
||||
switch (src->sa_family)
|
||||
{
|
||||
case AF_INET:
|
||||
{
|
||||
|
@ -137,7 +137,7 @@ void ddsi_ipaddr_to_loc (nn_locator_t *dst, const os_sockaddr_storage *src, int3
|
|||
}
|
||||
#endif
|
||||
default:
|
||||
NN_FATAL ("nn_address_to_loc: family %d unsupported\n", (int) src->ss_family);
|
||||
NN_FATAL ("nn_address_to_loc: family %d unsupported\n", (int) src->sa_family);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -347,43 +347,13 @@ static void ddsi_raweth_deinit(void)
|
|||
}
|
||||
}
|
||||
|
||||
static int ddsi_raweth_enumerate_interfaces (ddsi_tran_factory_t factory, int max, struct os_ifAttributes_s *interfs)
|
||||
static int ddsi_raweth_enumerate_interfaces (ddsi_tran_factory_t factory, os_ifaddrs_t **interfs)
|
||||
{
|
||||
struct ifaddrs *ifaddr, *ifa;
|
||||
int cnt = 0;
|
||||
int afs[] = { AF_PACKET, OS_AF_NULL };
|
||||
|
||||
(void)factory;
|
||||
if (getifaddrs (&ifaddr) == -1)
|
||||
return -errno;
|
||||
for (ifa = ifaddr; ifa && cnt < max; ifa = ifa->ifa_next)
|
||||
{
|
||||
struct os_ifAttributes_s *f = &interfs[cnt];
|
||||
struct sockaddr_ll *x;
|
||||
if (ifa->ifa_addr == NULL)
|
||||
continue;
|
||||
if (ifa->ifa_addr->sa_family != AF_PACKET)
|
||||
continue;
|
||||
if ((ifa->ifa_flags & (IFF_UP | IFF_BROADCAST)) != (IFF_UP | IFF_BROADCAST))
|
||||
continue;
|
||||
strncpy(f->name, ifa->ifa_name, sizeof(f->name));
|
||||
f->name[sizeof(f->name)-1] = 0;
|
||||
f->flags = ifa->ifa_flags;
|
||||
f->interfaceIndexNo = if_nametoindex(f->name);
|
||||
x = (struct sockaddr_ll *)&f->address;
|
||||
memcpy(x, ifa->ifa_addr, sizeof (*x));
|
||||
x = (struct sockaddr_ll *)&f->network_mask;
|
||||
if (ifa->ifa_netmask)
|
||||
memcpy(x, ifa->ifa_netmask, sizeof (*x));
|
||||
else
|
||||
memset(x, 0, sizeof(*x));
|
||||
x = (struct sockaddr_ll *)&f->broadcast_address;
|
||||
if (ifa->ifa_broadaddr)
|
||||
memcpy(x, ifa->ifa_broadaddr, sizeof (*x));
|
||||
else
|
||||
memset(x, 0, sizeof(*x));
|
||||
cnt++;
|
||||
}
|
||||
freeifaddrs (ifaddr);
|
||||
return cnt;
|
||||
|
||||
return -os_getifaddrs(interfs, afs);
|
||||
}
|
||||
|
||||
int ddsi_raweth_init (void)
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "ddsi_eth.h"
|
||||
#include "ddsi/ddsi_tran.h"
|
||||
#include "ddsi/ddsi_tcp.h"
|
||||
#include "ddsi/ddsi_ipaddr.h"
|
||||
|
@ -82,43 +83,16 @@ static void nn_trace_tcp (const char *fmt, ...)
|
|||
|
||||
#define TRACE_TCP(args) ((config.enabled_logcats & LC_TCP) ? (nn_trace_tcp args) : (void) 0)
|
||||
|
||||
static unsigned short sockaddr_get_port (const os_sockaddr_storage *addr)
|
||||
{
|
||||
if (addr->ss_family == AF_INET)
|
||||
return ntohs (((os_sockaddr_in *) addr)->sin_port);
|
||||
#if OS_SOCKET_HAS_IPV6
|
||||
else
|
||||
return ntohs (((os_sockaddr_in6 *) addr)->sin6_port);
|
||||
#endif
|
||||
}
|
||||
|
||||
static int ddsi_tcp_cmp_conn (const ddsi_tcp_conn_t c1, const ddsi_tcp_conn_t c2)
|
||||
{
|
||||
const os_sockaddr_storage *a1s = &c1->m_peer_addr;
|
||||
const os_sockaddr_storage *a2s = &c2->m_peer_addr;
|
||||
if (a1s->ss_family != a2s->ss_family)
|
||||
return (a1s->ss_family < a2s->ss_family) ? -1 : 1;
|
||||
const os_sockaddr *a1s = (os_sockaddr *)&c1->m_peer_addr;
|
||||
const os_sockaddr *a2s = (os_sockaddr *)&c2->m_peer_addr;
|
||||
if (a1s->sa_family != a2s->sa_family)
|
||||
return (a1s->sa_family < a2s->sa_family) ? -1 : 1;
|
||||
else if (c1->m_peer_port != c2->m_peer_port)
|
||||
return (c1->m_peer_port < c2->m_peer_port) ? -1 : 1;
|
||||
else if (a1s->ss_family == AF_INET)
|
||||
{
|
||||
const os_sockaddr_in *a1 = (const os_sockaddr_in *) a1s;
|
||||
const os_sockaddr_in *a2 = (const os_sockaddr_in *) a2s;
|
||||
return (a1->sin_addr.s_addr == a2->sin_addr.s_addr) ? 0 : (a1->sin_addr.s_addr < a2->sin_addr.s_addr) ? -1 : 1;
|
||||
}
|
||||
#if OS_SOCKET_HAS_IPV6
|
||||
else if (a1s->ss_family == AF_INET6)
|
||||
{
|
||||
const os_sockaddr_in6 *a1 = (const os_sockaddr_in6 *) a1s;
|
||||
const os_sockaddr_in6 *a2 = (const os_sockaddr_in6 *) a2s;
|
||||
return memcmp (&a1->sin6_addr, &a2->sin6_addr, 16);
|
||||
}
|
||||
#endif
|
||||
else
|
||||
{
|
||||
assert (0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return os_sockaddr_compare(a1s, a2s);
|
||||
}
|
||||
|
||||
typedef struct ddsi_tcp_node
|
||||
|
@ -140,12 +114,12 @@ static os_mutex ddsi_tcp_cache_lock_g;
|
|||
static ut_avlTree_t ddsi_tcp_cache_g;
|
||||
static struct ddsi_tran_factory ddsi_tcp_factory_g;
|
||||
|
||||
static ddsi_tcp_conn_t ddsi_tcp_new_conn (os_socket, bool, os_sockaddr_storage *);
|
||||
static ddsi_tcp_conn_t ddsi_tcp_new_conn (os_socket, bool, os_sockaddr *);
|
||||
|
||||
static char *sockaddr_to_string_with_port (char *dst, size_t sizeof_dst, const os_sockaddr_storage *src)
|
||||
static char *sockaddr_to_string_with_port (char *dst, size_t sizeof_dst, const os_sockaddr *src)
|
||||
{
|
||||
nn_locator_t loc;
|
||||
ddsi_ipaddr_to_loc(&loc, src, src->ss_family == AF_INET ? NN_LOCATOR_KIND_TCPv4 : NN_LOCATOR_KIND_TCPv6);
|
||||
ddsi_ipaddr_to_loc(&loc, src, src->sa_family == AF_INET ? NN_LOCATOR_KIND_TCPv4 : NN_LOCATOR_KIND_TCPv6);
|
||||
ddsi_locator_to_string(dst, sizeof_dst, &loc);
|
||||
return dst;
|
||||
}
|
||||
|
@ -185,7 +159,7 @@ static unsigned short get_socket_port (os_socket socket)
|
|||
NN_ERROR ("ddsi_tcp_get_socket_port: getsockname errno %d\n", err);
|
||||
return 0;
|
||||
}
|
||||
return sockaddr_get_port(&addr);
|
||||
return os_sockaddr_get_port((os_sockaddr *)&addr);
|
||||
}
|
||||
|
||||
static void ddsi_tcp_conn_set_socket (ddsi_tcp_conn_t conn, os_socket sock)
|
||||
|
@ -257,7 +231,7 @@ static void ddsi_tcp_conn_connect (ddsi_tcp_conn_t conn, const struct msghdr * m
|
|||
}
|
||||
#endif
|
||||
|
||||
sockaddr_to_string_with_port(buff, sizeof(buff), (const os_sockaddr_storage *) msg->msg_name);
|
||||
sockaddr_to_string_with_port(buff, sizeof(buff), (os_sockaddr *) msg->msg_name);
|
||||
nn_log (LC_INFO, "%s connect socket %"PRIsock" port %u to %s\n", ddsi_name, sock, get_socket_port (sock), buff);
|
||||
|
||||
/* Also may need to receive on connection so add to waitset */
|
||||
|
@ -305,7 +279,7 @@ static void ddsi_tcp_cache_add (ddsi_tcp_conn_t conn, ut_avlIPath_t * path)
|
|||
}
|
||||
}
|
||||
|
||||
sockaddr_to_string_with_port(buff, sizeof(buff), &conn->m_peer_addr);
|
||||
sockaddr_to_string_with_port(buff, sizeof(buff), (os_sockaddr *)&conn->m_peer_addr);
|
||||
nn_log (LC_INFO, "%s cache %s %s socket %"PRIsock" to %s\n", ddsi_name, action, conn->m_base.m_server ? "server" : "client", conn->m_sock, buff);
|
||||
}
|
||||
|
||||
|
@ -319,7 +293,7 @@ static void ddsi_tcp_cache_remove (ddsi_tcp_conn_t conn)
|
|||
node = ut_avlLookupDPath (&ddsi_tcp_treedef, &ddsi_tcp_cache_g, conn, &path);
|
||||
if (node)
|
||||
{
|
||||
sockaddr_to_string_with_port(buff, sizeof(buff), &conn->m_peer_addr);
|
||||
sockaddr_to_string_with_port(buff, sizeof(buff), (os_sockaddr *)&conn->m_peer_addr);
|
||||
nn_log (LC_INFO, "%s cache removed socket %"PRIsock" to %s\n", ddsi_name, conn->m_sock, buff);
|
||||
ut_avlDeleteDPath (&ddsi_tcp_treedef, &ddsi_tcp_cache_g, node, &path);
|
||||
ddsi_tcp_node_free (node);
|
||||
|
@ -340,7 +314,7 @@ static ddsi_tcp_conn_t ddsi_tcp_cache_find (const struct msghdr * msg)
|
|||
ddsi_tcp_conn_t ret = NULL;
|
||||
|
||||
memset (&key, 0, sizeof (key));
|
||||
key.m_peer_port = sockaddr_get_port (msg->msg_name);
|
||||
key.m_peer_port = os_sockaddr_get_port (msg->msg_name);
|
||||
memcpy (&key.m_peer_addr, msg->msg_name, msg->msg_namelen);
|
||||
|
||||
/* Check cache for existing connection to target */
|
||||
|
@ -361,7 +335,7 @@ static ddsi_tcp_conn_t ddsi_tcp_cache_find (const struct msghdr * msg)
|
|||
}
|
||||
if (ret == NULL)
|
||||
{
|
||||
ret = ddsi_tcp_new_conn (Q_INVALID_SOCKET, false, &key.m_peer_addr);
|
||||
ret = ddsi_tcp_new_conn (Q_INVALID_SOCKET, false, (os_sockaddr *)&key.m_peer_addr);
|
||||
ddsi_tcp_cache_add (ret, &path);
|
||||
}
|
||||
os_mutexUnlock (&ddsi_tcp_cache_lock_g);
|
||||
|
@ -452,7 +426,7 @@ static ssize_t ddsi_tcp_conn_read (ddsi_tran_conn_t conn, unsigned char * buf, s
|
|||
{
|
||||
if (srcloc)
|
||||
{
|
||||
ddsi_ipaddr_to_loc(srcloc, &tcp->m_peer_addr, tcp->m_peer_addr.ss_family == AF_INET ? NN_LOCATOR_KIND_TCPv4 : NN_LOCATOR_KIND_TCPv6);
|
||||
ddsi_ipaddr_to_loc(srcloc, (os_sockaddr *)&tcp->m_peer_addr, tcp->m_peer_addr.ss_family == AF_INET ? NN_LOCATOR_KIND_TCPv4 : NN_LOCATOR_KIND_TCPv6);
|
||||
}
|
||||
return (ssize_t) pos;
|
||||
}
|
||||
|
@ -586,7 +560,7 @@ static ssize_t ddsi_tcp_conn_write (ddsi_tran_conn_t base, const nn_locator_t *d
|
|||
memset(&msg, 0, sizeof(msg));
|
||||
set_msghdr_iov (&msg, (ddsi_iovec_t *) iov, niov);
|
||||
msg.msg_name = &dstaddr;
|
||||
msg.msg_namelen = (socklen_t) os_sockaddrSizeof((os_sockaddr *) &dstaddr);
|
||||
msg.msg_namelen = (socklen_t) os_sockaddr_get_size((os_sockaddr *) &dstaddr);
|
||||
#if SYSDEPS_MSGHDR_FLAGS
|
||||
msg.msg_flags = (int) flags;
|
||||
#endif
|
||||
|
@ -822,7 +796,7 @@ static ddsi_tran_conn_t ddsi_tcp_accept (ddsi_tran_listener_t listener)
|
|||
if (sock == Q_INVALID_SOCKET)
|
||||
{
|
||||
getsockname (tl->m_sock, (struct sockaddr *) &addr, &addrlen);
|
||||
sockaddr_to_string_with_port(buff, sizeof(buff), &addr);
|
||||
sockaddr_to_string_with_port(buff, sizeof(buff), (os_sockaddr *)&addr);
|
||||
nn_log ((err == 0) ? LC_ERROR : LC_FATAL, "%s accept failed on socket %"PRIsock" at %s errno %d\n", ddsi_name, tl->m_sock, buff, err);
|
||||
}
|
||||
else if (getpeername (sock, (struct sockaddr *) &addr, &addrlen) == -1)
|
||||
|
@ -832,11 +806,11 @@ static ddsi_tran_conn_t ddsi_tcp_accept (ddsi_tran_listener_t listener)
|
|||
}
|
||||
else
|
||||
{
|
||||
sockaddr_to_string_with_port(buff, sizeof(buff), &addr);
|
||||
sockaddr_to_string_with_port(buff, sizeof(buff), (os_sockaddr *)&addr);
|
||||
nn_log (LC_INFO, "%s accept new socket %"PRIsock" on socket %"PRIsock" from %s\n", ddsi_name, sock, tl->m_sock, buff);
|
||||
|
||||
os_sockSetNonBlocking (sock, true);
|
||||
tcp = ddsi_tcp_new_conn (sock, true, &addr);
|
||||
tcp = ddsi_tcp_new_conn (sock, true, (os_sockaddr *)&addr);
|
||||
#ifdef DDSI_INCLUDE_SSL
|
||||
tcp->m_ssl = ssl;
|
||||
#endif
|
||||
|
@ -869,7 +843,7 @@ static void ddsi_tcp_conn_peer_locator (ddsi_tran_conn_t conn, nn_locator_t * lo
|
|||
char buff[DDSI_LOCSTRLEN];
|
||||
ddsi_tcp_conn_t tc = (ddsi_tcp_conn_t) conn;
|
||||
assert (tc->m_sock != Q_INVALID_SOCKET);
|
||||
ddsi_ipaddr_to_loc (loc, &tc->m_peer_addr, tc->m_peer_addr.ss_family == AF_INET ? NN_LOCATOR_KIND_TCPv4 : NN_LOCATOR_KIND_TCPv6);
|
||||
ddsi_ipaddr_to_loc (loc, (os_sockaddr *)&tc->m_peer_addr, tc->m_peer_addr.ss_family == AF_INET ? NN_LOCATOR_KIND_TCPv4 : NN_LOCATOR_KIND_TCPv6);
|
||||
ddsi_locator_to_string(buff, sizeof(buff), loc);
|
||||
TRACE (("(%s EP:%s)", ddsi_name, buff));
|
||||
}
|
||||
|
@ -885,7 +859,7 @@ static void ddsi_tcp_base_init (struct ddsi_tran_conn * base)
|
|||
base->m_peer_locator_fn = ddsi_tcp_conn_peer_locator;
|
||||
}
|
||||
|
||||
static ddsi_tcp_conn_t ddsi_tcp_new_conn (os_socket sock, bool server, os_sockaddr_storage * peer)
|
||||
static ddsi_tcp_conn_t ddsi_tcp_new_conn (os_socket sock, bool server, os_sockaddr * peer)
|
||||
{
|
||||
ddsi_tcp_conn_t conn = (ddsi_tcp_conn_t) os_malloc (sizeof (*conn));
|
||||
|
||||
|
@ -893,8 +867,8 @@ static ddsi_tcp_conn_t ddsi_tcp_new_conn (os_socket sock, bool server, os_sockad
|
|||
ddsi_tcp_base_init (&conn->m_base);
|
||||
os_mutexInit (&conn->m_mutex);
|
||||
conn->m_sock = Q_INVALID_SOCKET;
|
||||
conn->m_peer_addr = *peer;
|
||||
conn->m_peer_port = sockaddr_get_port (peer);
|
||||
(void)memcpy(&conn->m_peer_addr, peer, os_sockaddr_get_size(peer));
|
||||
conn->m_peer_port = os_sockaddr_get_port (peer);
|
||||
conn->m_base.m_server = server;
|
||||
conn->m_base.m_base.m_port = INVALID_PORT;
|
||||
ddsi_tcp_conn_set_socket (conn, sock);
|
||||
|
@ -939,7 +913,7 @@ static ddsi_tran_listener_t ddsi_tcp_create_listener (int port, ddsi_tran_qos_t
|
|||
return NULL;
|
||||
}
|
||||
|
||||
sockaddr_to_string_with_port(buff, sizeof(buff), &addr);
|
||||
sockaddr_to_string_with_port(buff, sizeof(buff), (os_sockaddr *)&addr);
|
||||
nn_log (LC_INFO, "%s create listener socket %"PRIsock" on %s\n", ddsi_name, sock, buff);
|
||||
}
|
||||
|
||||
|
@ -949,7 +923,7 @@ static ddsi_tran_listener_t ddsi_tcp_create_listener (int port, ddsi_tran_qos_t
|
|||
static void ddsi_tcp_conn_delete (ddsi_tcp_conn_t conn)
|
||||
{
|
||||
char buff[DDSI_LOCSTRLEN];
|
||||
sockaddr_to_string_with_port(buff, sizeof(buff), &conn->m_peer_addr);
|
||||
sockaddr_to_string_with_port(buff, sizeof(buff), (os_sockaddr *)&conn->m_peer_addr);
|
||||
nn_log (LC_INFO, "%s free %s connnection on socket %"PRIsock" to %s\n", ddsi_name, conn->m_base.m_server ? "server" : "client", conn->m_sock, buff);
|
||||
|
||||
#ifdef DDSI_INCLUDE_SSL
|
||||
|
@ -973,10 +947,10 @@ static void ddsi_tcp_close_conn (ddsi_tran_conn_t tc)
|
|||
char buff[DDSI_LOCSTRLEN];
|
||||
nn_locator_t loc;
|
||||
ddsi_tcp_conn_t conn = (ddsi_tcp_conn_t) tc;
|
||||
sockaddr_to_string_with_port(buff, sizeof(buff), &conn->m_peer_addr);
|
||||
sockaddr_to_string_with_port(buff, sizeof(buff), (os_sockaddr *)&conn->m_peer_addr);
|
||||
nn_log (LC_INFO, "%s close %s connnection on socket %"PRIsock" to %s\n", ddsi_name, conn->m_base.m_server ? "server" : "client", conn->m_sock, buff);
|
||||
(void) shutdown (conn->m_sock, 2);
|
||||
ddsi_ipaddr_to_loc(&loc, &conn->m_peer_addr, conn->m_peer_addr.ss_family == AF_INET ? NN_LOCATOR_KIND_TCPv4 : NN_LOCATOR_KIND_TCPv6);
|
||||
ddsi_ipaddr_to_loc(&loc, (os_sockaddr *)&conn->m_peer_addr, conn->m_peer_addr.ss_family == AF_INET ? NN_LOCATOR_KIND_TCPv4 : NN_LOCATOR_KIND_TCPv6);
|
||||
loc.port = conn->m_peer_port;
|
||||
purge_proxy_participants (&loc, conn->m_base.m_server);
|
||||
}
|
||||
|
@ -1035,13 +1009,13 @@ static void ddsi_tcp_unblock_listener (ddsi_tran_listener_t listener)
|
|||
}
|
||||
do
|
||||
{
|
||||
ret = connect (sock, (struct sockaddr *) &addr, (unsigned) os_sockaddrSizeof((os_sockaddr *)&addr));
|
||||
ret = connect (sock, (struct sockaddr *) &addr, (unsigned) os_sockaddr_get_size((os_sockaddr *)&addr));
|
||||
}
|
||||
while ((ret == -1) && (os_getErrno() == os_sockEINTR));
|
||||
if (ret == -1)
|
||||
{
|
||||
char buff[DDSI_LOCSTRLEN];
|
||||
sockaddr_to_string_with_port(buff, sizeof(buff), &addr);
|
||||
sockaddr_to_string_with_port(buff, sizeof(buff), (os_sockaddr *)&addr);
|
||||
nn_log (LC_WARNING, "%s failed to connect to own listener (%s) error %d\n", ddsi_name, buff, os_getErrno());
|
||||
}
|
||||
}
|
||||
|
@ -1093,6 +1067,7 @@ int ddsi_tcp_init (void)
|
|||
ddsi_tcp_factory_g.m_free_fn = ddsi_tcp_release_factory;
|
||||
ddsi_tcp_factory_g.m_locator_from_string_fn = ddsi_tcp_address_from_string;
|
||||
ddsi_tcp_factory_g.m_locator_to_string_fn = ddsi_ipaddr_to_string;
|
||||
ddsi_tcp_factory_g.m_enumerate_interfaces_fn = ddsi_eth_enumerate_interfaces;
|
||||
ddsi_factory_add (&ddsi_tcp_factory_g);
|
||||
|
||||
#if OS_SOCKET_HAS_IPV6
|
||||
|
|
|
@ -332,10 +332,7 @@ char *ddsi_locator_to_string_no_port (char *dst, size_t sizeof_dst, const nn_loc
|
|||
return dst;
|
||||
}
|
||||
|
||||
int ddsi_enumerate_interfaces (ddsi_tran_factory_t factory, int max, struct os_ifAttributes_s *interfs)
|
||||
int ddsi_enumerate_interfaces (ddsi_tran_factory_t factory, os_ifaddrs_t **interfs)
|
||||
{
|
||||
/* FIXME: HACK */
|
||||
if (factory->m_enumerate_interfaces_fn == 0)
|
||||
return 0;
|
||||
return factory->m_enumerate_interfaces_fn (factory, max, interfs);
|
||||
return factory->m_enumerate_interfaces_fn (factory, interfs);
|
||||
}
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#include <string.h>
|
||||
#include "os/os.h"
|
||||
#include "os/os_atomics.h"
|
||||
#include "ddsi_eth.h"
|
||||
#include "ddsi/ddsi_tran.h"
|
||||
#include "ddsi/ddsi_udp.h"
|
||||
#include "ddsi/ddsi_ipaddr.h"
|
||||
|
@ -79,7 +80,7 @@ static ssize_t ddsi_udp_conn_read (ddsi_tran_conn_t conn, unsigned char * buf, s
|
|||
if (ret > 0)
|
||||
{
|
||||
if (srcloc)
|
||||
ddsi_ipaddr_to_loc(srcloc, &src, src.ss_family == AF_INET ? NN_LOCATOR_KIND_UDPv4 : NN_LOCATOR_KIND_UDPv6);
|
||||
ddsi_ipaddr_to_loc(srcloc, (os_sockaddr *)&src, src.ss_family == AF_INET ? NN_LOCATOR_KIND_UDPv4 : NN_LOCATOR_KIND_UDPv6);
|
||||
|
||||
/* Check for udp packet truncation */
|
||||
if ((((size_t) ret) > len)
|
||||
|
@ -90,7 +91,7 @@ static ssize_t ddsi_udp_conn_read (ddsi_tran_conn_t conn, unsigned char * buf, s
|
|||
{
|
||||
char addrbuf[DDSI_LOCSTRLEN];
|
||||
nn_locator_t tmp;
|
||||
ddsi_ipaddr_to_loc(&tmp, &src, src.ss_family == AF_INET ? NN_LOCATOR_KIND_UDPv4 : NN_LOCATOR_KIND_UDPv6);
|
||||
ddsi_ipaddr_to_loc(&tmp, (os_sockaddr *)&src, src.ss_family == AF_INET ? NN_LOCATOR_KIND_UDPv4 : NN_LOCATOR_KIND_UDPv6);
|
||||
ddsi_locator_to_string(addrbuf, sizeof(addrbuf), &tmp);
|
||||
NN_WARNING ("%s => %d truncated to %d\n", addrbuf, (int)ret, (int)len);
|
||||
}
|
||||
|
@ -120,7 +121,7 @@ static ssize_t ddsi_udp_conn_write (ddsi_tran_conn_t conn, const nn_locator_t *d
|
|||
ddsi_ipaddr_from_loc(&dstaddr, dst);
|
||||
set_msghdr_iov (&msg, (ddsi_iovec_t *) iov, niov);
|
||||
msg.msg_name = &dstaddr;
|
||||
msg.msg_namelen = (socklen_t) os_sockaddrSizeof((os_sockaddr *) &dstaddr);
|
||||
msg.msg_namelen = (socklen_t) os_sockaddr_get_size((os_sockaddr *) &dstaddr);
|
||||
#if !defined(__sun) || defined(_XPG4_2)
|
||||
msg.msg_control = NULL;
|
||||
msg.msg_controllen = 0;
|
||||
|
@ -200,16 +201,6 @@ static int ddsi_udp_conn_locator (ddsi_tran_base_t base, nn_locator_t *loc)
|
|||
return ret;
|
||||
}
|
||||
|
||||
static unsigned short sockaddr_get_port (const os_sockaddr_storage *addr)
|
||||
{
|
||||
if (addr->ss_family == AF_INET)
|
||||
return ntohs (((os_sockaddr_in *) addr)->sin_port);
|
||||
#if OS_SOCKET_HAS_IPV6
|
||||
else
|
||||
return ntohs (((os_sockaddr_in6 *) addr)->sin6_port);
|
||||
#endif
|
||||
}
|
||||
|
||||
static unsigned short get_socket_port (os_socket socket)
|
||||
{
|
||||
os_sockaddr_storage addr;
|
||||
|
@ -220,7 +211,8 @@ static unsigned short get_socket_port (os_socket socket)
|
|||
NN_ERROR ("ddsi_udp_get_socket_port: getsockname errno %d\n", err);
|
||||
return 0;
|
||||
}
|
||||
return sockaddr_get_port(&addr);
|
||||
|
||||
return os_sockaddr_get_port((os_sockaddr *)&addr);
|
||||
}
|
||||
|
||||
static ddsi_tran_conn_t ddsi_udp_create_conn
|
||||
|
@ -531,6 +523,7 @@ int ddsi_udp_init (void)
|
|||
ddsi_udp_factory_g.m_is_nearby_address_fn = ddsi_ipaddr_is_nearby_address;
|
||||
ddsi_udp_factory_g.m_locator_from_string_fn = ddsi_udp_address_from_string;
|
||||
ddsi_udp_factory_g.m_locator_to_string_fn = ddsi_udp_locator_to_string;
|
||||
ddsi_udp_factory_g.m_enumerate_interfaces_fn = ddsi_eth_enumerate_interfaces;
|
||||
#if OS_SOCKET_HAS_IPV6
|
||||
if (config.transport_selector == TRANS_UDP6)
|
||||
{
|
||||
|
|
|
@ -455,63 +455,33 @@ int find_own_ip (const char *requested_address)
|
|||
const char *sep = " ";
|
||||
char last_if_name[80] = "";
|
||||
int quality = -1;
|
||||
os_result res;
|
||||
int i;
|
||||
unsigned int nif;
|
||||
os_ifAttributes *ifs;
|
||||
os_ifaddrs_t *ifa, *ifa_root = NULL;
|
||||
int maxq_list[MAX_INTERFACES];
|
||||
int maxq_count = 0;
|
||||
size_t maxq_strlen = 0;
|
||||
int selected_idx = -1;
|
||||
char addrbuf[DDSI_LOCSTRLEN];
|
||||
|
||||
ifs = os_malloc (MAX_INTERFACES * sizeof (*ifs));
|
||||
|
||||
nn_log (LC_CONFIG, "interfaces:");
|
||||
|
||||
{
|
||||
int retcode;
|
||||
nif = 0;
|
||||
retcode = ddsi_enumerate_interfaces(gv.m_factory, (int)(MAX_INTERFACES - nif), ifs);
|
||||
if (retcode > 0)
|
||||
{
|
||||
nif = (unsigned)retcode;
|
||||
res = os_resultSuccess;
|
||||
}
|
||||
else if (retcode < 0)
|
||||
{
|
||||
NN_ERROR ("ddsi_enumerate_interfaces(%s): %d\n", gv.m_factory->m_typename, retcode);
|
||||
res = os_resultFail;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (config.transport_selector == TRANS_TCP6 || config.transport_selector == TRANS_UDP6)
|
||||
res = os_sockQueryIPv6Interfaces (ifs, MAX_INTERFACES, &nif);
|
||||
else if (config.transport_selector == TRANS_TCP || config.transport_selector == TRANS_UDP)
|
||||
res = os_sockQueryInterfaces (ifs, MAX_INTERFACES, &nif);
|
||||
else
|
||||
{
|
||||
NN_ERROR ("ddsi_enumerate_interfaces(%s): no go but neither UDP[46] nor TCP[46]\n", gv.m_factory->m_typename);
|
||||
res = os_resultFail;
|
||||
}
|
||||
}
|
||||
if (res != os_resultSuccess)
|
||||
{
|
||||
NN_ERROR ("os_sockQueryInterfaces: %d\n", (int) res);
|
||||
os_free (ifs);
|
||||
int ret;
|
||||
ret = ddsi_enumerate_interfaces(gv.m_factory, &ifa_root);
|
||||
if (ret < 0) {
|
||||
NN_ERROR("ddsi_enumerate_interfaces(%s): %d\n", gv.m_factory->m_typename, ret);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
gv.n_interfaces = 0;
|
||||
last_if_name[0] = 0;
|
||||
for (i = 0; i < (int) nif; i++, sep = ", ")
|
||||
for (ifa = ifa_root; ifa != NULL; ifa = ifa->next)
|
||||
{
|
||||
os_sockaddr_storage tmpip, tmpmask;
|
||||
char if_name[sizeof (last_if_name)];
|
||||
int q = 0;
|
||||
|
||||
strncpy (if_name, ifs[i].name, sizeof (if_name) - 1);
|
||||
strncpy (if_name, ifa->name, sizeof (if_name) - 1);
|
||||
if_name[sizeof (if_name) - 1] = 0;
|
||||
|
||||
if (strcmp (if_name, last_if_name))
|
||||
|
@ -519,46 +489,46 @@ int find_own_ip (const char *requested_address)
|
|||
strcpy (last_if_name, if_name);
|
||||
|
||||
/* interface must be up */
|
||||
if ((ifs[i].flags & IFF_UP) == 0)
|
||||
{
|
||||
if ((ifa->flags & IFF_UP) == 0) {
|
||||
nn_log (LC_CONFIG, " (interface down)");
|
||||
continue;
|
||||
} else if (os_sockaddr_is_unspecified(ifa->addr)) {
|
||||
nn_log (LC_CONFIG, " (address unspecified)");
|
||||
continue;
|
||||
}
|
||||
|
||||
tmpip = ifs[i].address;
|
||||
tmpmask = ifs[i].network_mask;
|
||||
#ifdef __linux
|
||||
if (tmpip.ss_family == AF_PACKET)
|
||||
if (ifa->addr->sa_family == AF_PACKET)
|
||||
{
|
||||
/* FIXME: weirdo warning warranted */
|
||||
nn_locator_t *l = &gv.interfaces[gv.n_interfaces].loc;
|
||||
l->kind = NN_LOCATOR_KIND_RAWETH;
|
||||
l->port = NN_LOCATOR_PORT_INVALID;
|
||||
memset(l->address, 0, 10);
|
||||
memcpy(l->address + 10, ((struct sockaddr_ll *)&tmpip)->sll_addr, 6);
|
||||
memcpy(l->address + 10, ((struct sockaddr_ll *)ifa->addr)->sll_addr, 6);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
ddsi_ipaddr_to_loc(&gv.interfaces[gv.n_interfaces].loc, &tmpip, gv.m_factory->m_kind);
|
||||
ddsi_ipaddr_to_loc(&gv.interfaces[gv.n_interfaces].loc, ifa->addr, gv.m_factory->m_kind);
|
||||
}
|
||||
ddsi_locator_to_string_no_port(addrbuf, sizeof(addrbuf), &gv.interfaces[gv.n_interfaces].loc);
|
||||
nn_log (LC_CONFIG, " %s(", addrbuf);
|
||||
|
||||
if (!(ifs[i].flags & IFF_MULTICAST) && multicast_override (if_name))
|
||||
if (!(ifa->flags & IFF_MULTICAST) && multicast_override (if_name))
|
||||
{
|
||||
nn_log (LC_CONFIG, "assume-mc:");
|
||||
ifs[i].flags |= IFF_MULTICAST;
|
||||
ifa->flags |= IFF_MULTICAST;
|
||||
}
|
||||
|
||||
if (ifs[i].flags & IFF_LOOPBACK)
|
||||
if (ifa->flags & IFF_LOOPBACK)
|
||||
{
|
||||
/* Loopback device has the lowest priority of every interface
|
||||
available, because the other interfaces at least in principle
|
||||
allow communicating with other machines. */
|
||||
q += 0;
|
||||
#if OS_SOCKET_HAS_IPV6
|
||||
if (!(tmpip.ss_family == AF_INET6 && IN6_IS_ADDR_LINKLOCAL (&((os_sockaddr_in6 *) &tmpip)->sin6_addr)))
|
||||
if (!(ifa->addr->sa_family == AF_INET6 && IN6_IS_ADDR_LINKLOCAL (&((os_sockaddr_in6 *)ifa->addr)->sin6_addr)))
|
||||
q += 1;
|
||||
#endif
|
||||
}
|
||||
|
@ -575,16 +545,16 @@ int find_own_ip (const char *requested_address)
|
|||
which it was received. But that means proper multi-homing
|
||||
support and has quite an impact in various places, not least of
|
||||
which is the abstraction layer. */
|
||||
if (!(tmpip.ss_family == AF_INET6 && IN6_IS_ADDR_LINKLOCAL (&((os_sockaddr_in6 *) &tmpip)->sin6_addr)))
|
||||
if (!(ifa->addr->sa_family == AF_INET6 && IN6_IS_ADDR_LINKLOCAL (&((os_sockaddr_in6 *)ifa->addr)->sin6_addr)))
|
||||
q += 5;
|
||||
#endif
|
||||
|
||||
/* We strongly prefer a multicast capable interface, if that's
|
||||
not available anything that's not point-to-point, or else we
|
||||
hope IP routing will take care of the issues. */
|
||||
if (ifs[i].flags & IFF_MULTICAST)
|
||||
if (ifa->flags & IFF_MULTICAST)
|
||||
q += 4;
|
||||
else if (!(ifs[i].flags & IFF_POINTOPOINT))
|
||||
else if (!(ifa->flags & IFF_POINTOPOINT))
|
||||
q += 3;
|
||||
else
|
||||
q += 2;
|
||||
|
@ -604,10 +574,9 @@ int find_own_ip (const char *requested_address)
|
|||
|
||||
/* FIXME: HACK HACK */
|
||||
//ddsi_ipaddr_to_loc(&gv.interfaces[gv.n_interfaces].loc, &tmpip, gv.m_factory->m_kind);
|
||||
if (tmpip.ss_family == AF_INET || tmpip.ss_family == AF_INET6)
|
||||
if (ifa->addr->sa_family == AF_INET || ifa->addr->sa_family == AF_INET6)
|
||||
{
|
||||
tmpmask.ss_family = tmpip.ss_family;
|
||||
ddsi_ipaddr_to_loc(&gv.interfaces[gv.n_interfaces].netmask, &tmpmask, gv.m_factory->m_kind);
|
||||
ddsi_ipaddr_to_loc(&gv.interfaces[gv.n_interfaces].netmask, ifa->netmask, gv.m_factory->m_kind);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -615,14 +584,14 @@ int find_own_ip (const char *requested_address)
|
|||
gv.interfaces[gv.n_interfaces].netmask.port = NN_LOCATOR_PORT_INVALID;
|
||||
memset(&gv.interfaces[gv.n_interfaces].netmask.address, 0, sizeof(gv.interfaces[gv.n_interfaces].netmask.address));
|
||||
}
|
||||
gv.interfaces[gv.n_interfaces].mc_capable = ((ifs[i].flags & IFF_MULTICAST) != 0);
|
||||
gv.interfaces[gv.n_interfaces].point_to_point = ((ifs[i].flags & IFF_POINTOPOINT) != 0);
|
||||
gv.interfaces[gv.n_interfaces].if_index = ifs[i].interfaceIndexNo;
|
||||
gv.interfaces[gv.n_interfaces].mc_capable = ((ifa->flags & IFF_MULTICAST) != 0);
|
||||
gv.interfaces[gv.n_interfaces].point_to_point = ((ifa->flags & IFF_POINTOPOINT) != 0);
|
||||
gv.interfaces[gv.n_interfaces].if_index = ifa->index;
|
||||
gv.interfaces[gv.n_interfaces].name = os_strdup (if_name);
|
||||
gv.n_interfaces++;
|
||||
}
|
||||
nn_log (LC_CONFIG, "\n");
|
||||
os_free (ifs);
|
||||
os_freeifaddrs (ifa_root);
|
||||
|
||||
if (requested_address == NULL)
|
||||
{
|
||||
|
|
|
@ -17,10 +17,10 @@ IF(${platform} IN_LIST posix_platforms)
|
|||
set(platform posix)
|
||||
ENDIF()
|
||||
|
||||
PREPEND(srcs_platform ${platform} os_platform_errno.c os_platform_heap.c os_platform_init.c os_platform_process.c os_platform_socket.c os_platform_stdlib.c os_platform_sync.c os_platform_thread.c os_platform_time.c)
|
||||
PREPEND(srcs_platform ${platform} os_platform_errno.c os_platform_heap.c os_platform_init.c os_platform_process.c os_platform_ifaddrs.c os_platform_socket.c os_platform_stdlib.c os_platform_sync.c os_platform_thread.c os_platform_time.c)
|
||||
|
||||
include (GenerateExportHeader)
|
||||
PREPEND(srcs_os "${CMAKE_CURRENT_SOURCE_DIR}/src" os_atomics.c os_init.c os_report.c os_socket.c os_thread.c os_time.c os_errno.c os_iter.c ${srcs_platform})
|
||||
PREPEND(srcs_os "${CMAKE_CURRENT_SOURCE_DIR}/src" os_atomics.c os_init.c os_report.c os_ifaddrs.c os_socket.c os_thread.c os_time.c os_errno.c os_iter.c ${srcs_platform})
|
||||
add_library(OSAPI ${srcs_os})
|
||||
|
||||
configure_file(
|
||||
|
|
|
@ -15,12 +15,6 @@
|
|||
#ifndef OS_SOCKET_HAS_IPV6
|
||||
#error "OS_SOCKET_HAS_IPV6 should have been defined by os_platform_socket.h"
|
||||
#endif
|
||||
#ifndef OS_IFNAMESIZE
|
||||
#error "OS_IFNAMESIZE should have been defined by os_platform_socket.h"
|
||||
#endif
|
||||
#ifndef OS_SOCKET_HAS_SA_LEN
|
||||
#error "OS_SOCKET_HAS_SA_LEN should have been defined by os_platform_socket.h"
|
||||
#endif
|
||||
#ifndef OS_NO_SIOCGIFINDEX
|
||||
#error "OS_NO_SIOCGIFINDEX should have been defined by os_platform_socket.h"
|
||||
#endif
|
||||
|
@ -94,11 +88,7 @@ extern "C" {
|
|||
typedef struct ipv6_mreq os_ipv6_mreq;
|
||||
typedef struct in6_addr os_in6_addr;
|
||||
|
||||
#if defined (OSPL_VXWORKS653)
|
||||
typedef struct sockaddr_in os_sockaddr_storage;
|
||||
#else
|
||||
typedef struct sockaddr_storage os_sockaddr_storage;
|
||||
#endif
|
||||
|
||||
typedef struct sockaddr_in6 os_sockaddr_in6;
|
||||
#endif
|
||||
|
@ -120,59 +110,49 @@ extern "C" {
|
|||
|
||||
#define SD_FLAG_IS_SET(flags, flag) ((((uint32_t)(flags) & (uint32_t)(flag))) != 0U)
|
||||
|
||||
/**
|
||||
* Structure to hold a network interface's attributes
|
||||
*/
|
||||
typedef struct os_ifAttributes_s {
|
||||
/**
|
||||
* The network interface name (or at least OS_IFNAMESIZE - 1 charcaters thereof)
|
||||
*/
|
||||
char name[OS_IFNAMESIZE];
|
||||
/**
|
||||
* Iff the interface is IPv4 holds the ioctl query result flags for this interface.
|
||||
*/
|
||||
#define OS_AF_NULL (-1)
|
||||
|
||||
/** Network interface attributes */
|
||||
typedef struct os_ifaddrs_s {
|
||||
struct os_ifaddrs_s *next;
|
||||
char *name;
|
||||
uint32_t index;
|
||||
uint32_t flags;
|
||||
/**
|
||||
* The network interface address of this interface.
|
||||
*/
|
||||
os_sockaddr_storage address;
|
||||
/**
|
||||
* Iff this is an IPv4 interface, holds the broadcast address for the sub-network this
|
||||
* interface is connected to.
|
||||
*/
|
||||
os_sockaddr_storage broadcast_address;
|
||||
/**
|
||||
* Iff this is an IPv4 interface, holds the subnet mast for this interface
|
||||
*/
|
||||
os_sockaddr_storage network_mask;
|
||||
/**
|
||||
* Holds the interface index for this interface.
|
||||
*/
|
||||
unsigned interfaceIndexNo;
|
||||
} os_ifAttributes;
|
||||
|
||||
OSAPI_EXPORT os_result
|
||||
os_sockQueryInterfaces(
|
||||
os_ifAttributes *ifList,
|
||||
uint32_t listSize,
|
||||
uint32_t *validElements);
|
||||
os_sockaddr *addr;
|
||||
os_sockaddr *netmask;
|
||||
os_sockaddr *broadaddr;
|
||||
} os_ifaddrs_t;
|
||||
|
||||
/**
|
||||
* Fill-in a pre-allocated list of os_ifAttributes_s with details of
|
||||
* the available IPv6 network interfaces.
|
||||
* @param listSize Number of elements there is space for in the list.
|
||||
* @param ifList Pointer to head of list
|
||||
* @param validElements Out param to hold the number of interfaces found
|
||||
* whose detauils have been returned.
|
||||
* @return os_resultSuccess if 0 or more interfaces were found, os_resultFail if
|
||||
* an error occurred.
|
||||
* @see os_sockQueryInterfaces
|
||||
* @brief Get interface addresses
|
||||
*
|
||||
* Retrieve network interfaces available on the local system and store
|
||||
* them in a linked list of os_ifaddrs_t structures.
|
||||
*
|
||||
* The data returned by os_getifaddrs() is dynamically allocated and should
|
||||
* be freed using os_freeifaddrs when no longer needed.
|
||||
*
|
||||
* @param[in,out] ifap Address of first os_ifaddrs_t structure in the list.
|
||||
* @param[in] afs NULL-terminated array of address families (AF_xyz) to
|
||||
* restrict resulting set of network interfaces too. NULL to
|
||||
* return all network interfaces for all supported address
|
||||
* families. Terminate the array with OS_AF_NULL.
|
||||
*
|
||||
* @returns Returns zero on success or a valid errno value on error.
|
||||
*/
|
||||
OSAPI_EXPORT os_result
|
||||
os_sockQueryIPv6Interfaces(
|
||||
os_ifAttributes *ifList,
|
||||
uint32_t listSize,
|
||||
uint32_t *validElements);
|
||||
OSAPI_EXPORT _Success_(return == 0) int
|
||||
os_getifaddrs(
|
||||
_Inout_ os_ifaddrs_t **ifap,
|
||||
_In_opt_ const int *afs);
|
||||
|
||||
/**
|
||||
* @brief Free os_ifaddrs_t structure list allocated by os_getifaddrs()
|
||||
*
|
||||
* @param[in] Address of first os_ifaddrs_t structure in the list.
|
||||
*/
|
||||
OSAPI_EXPORT void
|
||||
os_freeifaddrs(
|
||||
_Pre_maybenull_ _Post_ptr_invalid_ os_ifaddrs_t *ifa);
|
||||
|
||||
OSAPI_EXPORT os_socket
|
||||
os_sockNew(
|
||||
|
@ -271,20 +251,53 @@ extern "C" {
|
|||
os_time *timeout);
|
||||
#endif /* WIN32 */
|
||||
|
||||
/* docced in implementation file */
|
||||
OSAPI_EXPORT os_result
|
||||
os_sockaddrInit(os_sockaddr* sa,
|
||||
bool isIPv4); /* IPvX is poorly abstracted; this is temporary */
|
||||
/**
|
||||
* Returns size of socket address.
|
||||
* @param sa Socket address to return the size for.
|
||||
* @return Size of the socket address based on the address family, or 0 if
|
||||
* the address family is unknown.
|
||||
* @pre sa is a valid os_sockaddr pointer.
|
||||
*/
|
||||
OSAPI_EXPORT size_t
|
||||
os_sockaddr_get_size(
|
||||
const os_sockaddr *const sa) __nonnull_all__;
|
||||
|
||||
/* docced in implementation file */
|
||||
OSAPI_EXPORT bool
|
||||
os_sockaddrIPAddressEqual(const os_sockaddr* this_sock,
|
||||
const os_sockaddr* that_sock);
|
||||
/**
|
||||
* Retrieve port number from the given socket address.
|
||||
* @param sa Socket address to retrieve the port from.
|
||||
* @return Port number in host order.
|
||||
* @pre sa is a valid os_sockaddr pointer.
|
||||
*/
|
||||
OSAPI_EXPORT uint16_t
|
||||
os_sockaddr_get_port(const os_sockaddr *const sa) __nonnull_all__;
|
||||
|
||||
/**
|
||||
* Compare two IP addresses for equality - does not consider port number.
|
||||
* This is a 'straight' compare i.e. family must match and address bytes
|
||||
* must correspond. It does not consider the possibility of IPv6 mapped
|
||||
* IPv4 addresses or anything arcane like that.
|
||||
* @param sa1 First socket address
|
||||
* @param sa2 Second socket address.
|
||||
* @return true if equal, false otherwise.
|
||||
* @return Integer less than, equal to, or greater than zero if sa1 is
|
||||
* found, respectively, to be less than, to match, or be greater
|
||||
* than sa2.
|
||||
* @pre both sa1 and sa2 are valid os_sockaddr pointers.
|
||||
*/
|
||||
OSAPI_EXPORT int
|
||||
os_sockaddrIpAddressCompare(const os_sockaddr* addr1,
|
||||
const os_sockaddr* addr2) __nonnull_all__
|
||||
__attribute_pure__;
|
||||
os_sockaddr_compare(
|
||||
const os_sockaddr *const sa1,
|
||||
const os_sockaddr *const sa2) __nonnull_all__ __attribute_pure__;
|
||||
|
||||
/**
|
||||
* Check if IP address of given socket address is unspecified.
|
||||
* @param sa Socket address
|
||||
* @return true if unspecified, false otherwise.
|
||||
* @pre sa is a valid os_sockaddr pointer.
|
||||
*/
|
||||
OSAPI_EXPORT int
|
||||
os_sockaddr_is_unspecified(
|
||||
const os_sockaddr *const sa) __nonnull_all__;
|
||||
|
||||
/* docced in implementation file */
|
||||
OSAPI_EXPORT bool
|
||||
|
@ -303,20 +316,6 @@ extern "C" {
|
|||
os_sockaddrAddressToString(const os_sockaddr* sa,
|
||||
char* buffer, size_t buflen);
|
||||
|
||||
/**
|
||||
* Convert a socket address to a string format representation including the
|
||||
* portnumber.
|
||||
* @param sa The socket address struct.
|
||||
* @param buffer A character buffer to hold the string rep of the address.
|
||||
* @param buflen The (max) size of the buffer
|
||||
* @return Pointer to start of string
|
||||
*/
|
||||
OSAPI_EXPORT char*
|
||||
os_sockaddrAddressPortToString(
|
||||
const os_sockaddr* sa,
|
||||
char* buffer,
|
||||
size_t buflen);
|
||||
|
||||
/**
|
||||
* Convert the provided addressString into a os_sockaddr.
|
||||
*
|
||||
|
@ -342,16 +341,6 @@ extern "C" {
|
|||
OSAPI_EXPORT bool
|
||||
os_sockaddrIsLoopback(const os_sockaddr* thisSock);
|
||||
|
||||
/**
|
||||
* Returns sizeof(sa) based on the family of the actual content.
|
||||
* @param sa the sockaddr to get the actual size for
|
||||
* @return The actual size sa based on the family. If the family is
|
||||
* unknown 0 will be returned.
|
||||
* @pre sa is a valid sockaddr pointer
|
||||
*/
|
||||
OSAPI_EXPORT size_t
|
||||
os_sockaddrSizeof(const os_sockaddr* sa);
|
||||
|
||||
/**
|
||||
* Sets the address of the sockaddr to the special IN_ADDR_ANY value.
|
||||
* @param sa the sockaddr to set the address for
|
||||
|
@ -361,26 +350,6 @@ extern "C" {
|
|||
OSAPI_EXPORT void
|
||||
os_sockaddrSetInAddrAny(os_sockaddr* sa);
|
||||
|
||||
/**
|
||||
* Sets the port number in the supplied sockaddr.
|
||||
* @param sa the sockaddr to set the port in
|
||||
* @param port the port number to be set in network byte order
|
||||
* @pre sa is a valid sockaddr pointer
|
||||
* @post Port number of sa is set to port
|
||||
*/
|
||||
OSAPI_EXPORT void
|
||||
os_sockaddrSetPort(os_sockaddr* sa, uint16_t port);
|
||||
|
||||
/**
|
||||
* Retrieves the port number from the supplied sockaddr.
|
||||
* @param sa the sockaddr to retrieve the port from
|
||||
* @return The port number stored in the supplied sockaddr (hence in network byte order)
|
||||
* @pre sa is a valid sockaddr pointer
|
||||
*/
|
||||
OSAPI_EXPORT uint16_t
|
||||
os_sockaddrGetPort(const os_sockaddr* const sa);
|
||||
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
|
|
@ -262,6 +262,9 @@ extern "C" {
|
|||
__attribute_returns_nonnull__
|
||||
__attribute_warn_unused_result__;
|
||||
|
||||
void *
|
||||
os_memdup(const void *src, size_t n);
|
||||
|
||||
/** \brief os_strsep wrapper
|
||||
*
|
||||
* See strsep()
|
||||
|
@ -271,6 +274,14 @@ extern "C" {
|
|||
char **stringp,
|
||||
const char *delim);
|
||||
|
||||
/** \brief write a formatted string to a newly allocated buffer
|
||||
*/
|
||||
OSAPI_EXPORT int
|
||||
os_asprintf(
|
||||
char **strp,
|
||||
const char *fmt,
|
||||
...);
|
||||
|
||||
/** \brief os_vsnprintf wrapper
|
||||
*
|
||||
* Microsoft generates deprected warnings for vsnprintf,
|
||||
|
|
|
@ -39,7 +39,6 @@ extern "C" {
|
|||
|
||||
/* Keep defines before common header */
|
||||
#define OS_SOCKET_HAS_IPV6 1
|
||||
#define OS_IFNAMESIZE IF_NAMESIZE
|
||||
#define OS_SOCKET_HAS_SA_LEN 1
|
||||
#define OS_NO_SIOCGIFINDEX 1
|
||||
#define OS_NO_NETLINK 1
|
||||
|
|
|
@ -25,7 +25,6 @@ extern "C" {
|
|||
|
||||
/* Keep defines before common header */
|
||||
#define OS_SOCKET_HAS_IPV6 1
|
||||
#define OS_IFNAMESIZE 128
|
||||
#define OS_SOCKET_HAS_SA_LEN 0
|
||||
#define OS_NO_SIOCGIFINDEX 1
|
||||
#define OS_NO_NETLINK 1
|
||||
|
|
29
src/os/src/os_ifaddrs.c
Normal file
29
src/os/src/os_ifaddrs.c
Normal file
|
@ -0,0 +1,29 @@
|
|||
/*
|
||||
* Copyright(c) 2006 to 2018 ADLINK Technology Limited and others
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License v. 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
|
||||
* v. 1.0 which is available at
|
||||
* http://www.eclipse.org/org/documents/edl-v10.php.
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
|
||||
*/
|
||||
#include "os/os.h"
|
||||
|
||||
void
|
||||
os_freeifaddrs(os_ifaddrs_t *ifa)
|
||||
{
|
||||
os_ifaddrs_t *next;
|
||||
|
||||
while (ifa != NULL) {
|
||||
next = ifa->next;
|
||||
os_free(ifa->name);
|
||||
os_free(ifa->addr);
|
||||
os_free(ifa->netmask);
|
||||
os_free(ifa->broadaddr);
|
||||
os_free(ifa);
|
||||
ifa = next;
|
||||
}
|
||||
}
|
||||
|
|
@ -20,6 +20,11 @@
|
|||
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef __linux
|
||||
#include <linux/if_packet.h> /* sockaddr_ll */
|
||||
#endif /* __linux */
|
||||
|
||||
#include "os/os.h"
|
||||
|
||||
#if (OS_SOCKET_HAS_IPV6 == 1)
|
||||
|
@ -40,180 +45,125 @@ const os_in6_addr os_in6addr_loopback = { { { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 }
|
|||
#define OS_INET_PTON inet_pton
|
||||
#endif
|
||||
|
||||
static
|
||||
void os__sockaddrInit4(os_sockaddr* sa)
|
||||
const int afs[] = {
|
||||
#ifdef __linux
|
||||
AF_PACKET,
|
||||
#endif /* __linux */
|
||||
#if OS_SOCKET_HAS_IPV6
|
||||
AF_INET6,
|
||||
#endif /* OS_SOCKET_HAS_IPV6 */
|
||||
AF_INET,
|
||||
OS_AF_NULL /* Terminator */
|
||||
};
|
||||
|
||||
const int *const os_supp_afs = afs;
|
||||
|
||||
size_t
|
||||
os_sockaddr_get_size(const os_sockaddr *const sa)
|
||||
{
|
||||
assert(sa);
|
||||
/* 0 is a valid value for all members besides sa_family */
|
||||
memset(sa, 0, sizeof(os_sockaddr_in));
|
||||
sa->sa_family = AF_INET;
|
||||
size_t sz;
|
||||
|
||||
assert(sa != NULL);
|
||||
|
||||
switch(sa->sa_family) {
|
||||
#if OS_SOCKET_HAS_IPV6
|
||||
case AF_INET6:
|
||||
sz = sizeof(os_sockaddr_in6);
|
||||
break;
|
||||
#endif /* OS_SOCKET_HAS_IPV6 */
|
||||
#ifdef __linux
|
||||
case AF_PACKET:
|
||||
sz = sizeof(struct sockaddr_ll);
|
||||
break;
|
||||
#endif /* __linux */
|
||||
default:
|
||||
assert(sa->sa_family == AF_INET);
|
||||
sz = sizeof(os_sockaddr_in);
|
||||
break;
|
||||
}
|
||||
|
||||
return sz;
|
||||
}
|
||||
|
||||
|
||||
#if (OS_SOCKET_HAS_IPV6 == 1)
|
||||
static
|
||||
void os__sockaddrInit6(os_sockaddr* sa)
|
||||
uint16_t os_sockaddr_get_port(const os_sockaddr *const sa)
|
||||
{
|
||||
assert(sa);
|
||||
/* 0 is a valid value for all members besides sa_family */
|
||||
memset(sa, 0, sizeof(os_sockaddr_in6));
|
||||
sa->sa_family = AF_INET6;
|
||||
}
|
||||
#endif
|
||||
unsigned short port = 0;
|
||||
|
||||
|
||||
/**
|
||||
* Initialises the memory pointed to by sa. The address family
|
||||
* will be set correctly according to isIPv4.
|
||||
* @param sa Pointer to the os_sockaddr to be initialised
|
||||
* @param isIPv4 Flag indicating whether *sa will be IPv4 or IPv6. If
|
||||
* IPv6 is not supported but this flag is FALSE, sa will be initialised
|
||||
* as IPv4 and an API-warning is logged.
|
||||
* @pre sa != NULL
|
||||
* @return os_resultSuccess on successful initialisation, os_resultInvalid
|
||||
* if isIPv4 was FALSE but IPv6 is not supported.
|
||||
* @post sa is initialised
|
||||
* @note Please be aware that the memory will be memset; make sure that
|
||||
* enough memory for the requested address kind is available. Allocating
|
||||
* os_sockaddr_storage always suffices.
|
||||
*/
|
||||
os_result
|
||||
os_sockaddrInit(os_sockaddr* sa,
|
||||
bool isIPv4)
|
||||
{
|
||||
os_result result = os_resultSuccess;
|
||||
|
||||
assert(sa);
|
||||
if (!isIPv4)
|
||||
{
|
||||
#if (OS_SOCKET_HAS_IPV6 == 1)
|
||||
os__sockaddrInit6(sa);
|
||||
#else
|
||||
OS_ERROR("os_sockaddrInit", 0,
|
||||
"Unsupported parameter value: IPV6 address requested but not supported by this platform");
|
||||
os__sockaddrInit4(sa);
|
||||
result = os_resultInvalid;
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
os__sockaddrInit4(sa);
|
||||
switch(sa->sa_family) {
|
||||
#if OS_SOCKET_HAS_IPV6
|
||||
case AF_INET6:
|
||||
port = ntohs(((os_sockaddr_in6 *)sa)->sin6_port);
|
||||
break;
|
||||
#endif /* OS_SOCKET_HAS_IPV6 */
|
||||
default:
|
||||
assert(sa->sa_family == AF_INET);
|
||||
port = ntohs(((os_sockaddr_in *)sa)->sin_port);
|
||||
break;
|
||||
}
|
||||
|
||||
return result;
|
||||
return port;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Compare two socket IP host addresses for equality - does not consider the port number.
|
||||
* This is a 'straight' equal i.e. family must match and address bytes
|
||||
* must correspond. So it will not consider the possibility of IPv6 mapped
|
||||
* IPv4 addresses or anything arcane like that.
|
||||
* @param thisSock First address
|
||||
* @param thatSock Second address.
|
||||
* @return true if equal, false otherwise.
|
||||
*/
|
||||
bool
|
||||
os_sockaddrIPAddressEqual(const os_sockaddr* thisSock,
|
||||
const os_sockaddr* thatSock)
|
||||
int os_sockaddr_compare(
|
||||
const os_sockaddr *const sa1,
|
||||
const os_sockaddr *const sa2)
|
||||
{
|
||||
bool result = false;
|
||||
#if (OS_SOCKET_HAS_IPV6 == 1)
|
||||
os_sockaddr_in6 * thisV6, * thatV6;
|
||||
#endif
|
||||
int eq;
|
||||
size_t sz;
|
||||
|
||||
if (thisSock->sa_family == thatSock->sa_family)
|
||||
{
|
||||
if (thisSock->sa_family == AF_INET)
|
||||
{
|
||||
/* IPv4 */
|
||||
result = (((os_sockaddr_in*)thisSock)->sin_addr.s_addr ==
|
||||
((os_sockaddr_in*)thatSock)->sin_addr.s_addr ?
|
||||
true: false);
|
||||
}
|
||||
if ((eq = sa1->sa_family - sa2->sa_family) == 0) {
|
||||
switch(sa1->sa_family) {
|
||||
#if (OS_SOCKET_HAS_IPV6 == 1)
|
||||
else
|
||||
case AF_INET6:
|
||||
{
|
||||
/* IPv6 */
|
||||
thisV6 = (os_sockaddr_in6*) thisSock;
|
||||
thatV6 = (os_sockaddr_in6*) thatSock;
|
||||
result = (memcmp(&thisV6->sin6_addr.s6_addr, &thatV6->sin6_addr.s6_addr, sizeof(unsigned char) * 16) ?
|
||||
false : true);
|
||||
os_sockaddr_in6 *sin61, *sin62;
|
||||
sin61 = (os_sockaddr_in6 *)sa1;
|
||||
sin62 = (os_sockaddr_in6 *)sa2;
|
||||
sz = sizeof(sin61->sin6_addr);
|
||||
eq = memcmp(&sin61->sin6_addr, &sin62->sin6_addr, sz);
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
#endif /* OS_SOCKET_HAS_IPV6 */
|
||||
#ifdef __linux
|
||||
case AF_PACKET:
|
||||
{
|
||||
struct sockaddr_ll *sll1, *sll2;
|
||||
sll1 = (struct sockaddr_ll *)sa1;
|
||||
sll2 = (struct sockaddr_ll *)sa2;
|
||||
sz = sizeof(sll1->sll_addr);
|
||||
eq = memcmp(sll1->sll_addr, sll2->sll_addr, sz);
|
||||
}
|
||||
return result;
|
||||
break;
|
||||
#endif /* __linux */
|
||||
default:
|
||||
{
|
||||
assert(sa1->sa_family == AF_INET);
|
||||
os_sockaddr_in *sin1, *sin2;
|
||||
sin1 = (os_sockaddr_in *)sa1;
|
||||
sin2 = (os_sockaddr_in *)sa2;
|
||||
sz = sizeof(sin1->sin_addr);
|
||||
eq = memcmp(sin1, sin2, sizeof(*sin1));
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return eq;
|
||||
}
|
||||
|
||||
int
|
||||
os_sockaddrIpAddressCompare(const os_sockaddr* addr1,
|
||||
const os_sockaddr* addr2)
|
||||
int os_sockaddr_is_unspecified(const os_sockaddr *const sa)
|
||||
{
|
||||
int result = -1;
|
||||
uint16_t port1, port2;
|
||||
int r;
|
||||
int unspec = 0;
|
||||
|
||||
#if (OS_SOCKET_HAS_IPV6 == 1)
|
||||
os_sockaddr_in6 * thisV6, * thatV6;
|
||||
#endif
|
||||
assert(sa != NULL);
|
||||
|
||||
if (addr1->sa_family == addr2->sa_family)
|
||||
{
|
||||
if (addr1->sa_family == AF_INET)
|
||||
{
|
||||
/* IPv4 */
|
||||
if (((os_sockaddr_in*)addr1)->sin_addr.s_addr ==
|
||||
((os_sockaddr_in*)addr2)->sin_addr.s_addr) {
|
||||
port1 = os_sockaddrGetPort(addr1);
|
||||
port2 = os_sockaddrGetPort(addr2);
|
||||
if (port1 == port2) {
|
||||
result = 0;
|
||||
} else {
|
||||
if (port1 > port2) {
|
||||
result = 1;
|
||||
} else {
|
||||
result = -1;
|
||||
if (sa->sa_family == AF_INET6) {
|
||||
unspec = IN6_IS_ADDR_UNSPECIFIED(&((os_sockaddr_in6 *)sa)->sin6_addr);
|
||||
} else if (sa->sa_family == AF_INET) {
|
||||
unspec = (((os_sockaddr_in *)sa)->sin_addr.s_addr == 0);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (((os_sockaddr_in*)addr1)->sin_addr.s_addr >
|
||||
((os_sockaddr_in*)addr2)->sin_addr.s_addr) {
|
||||
result = 1;
|
||||
} else {
|
||||
result = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
#if (OS_SOCKET_HAS_IPV6 == 1)
|
||||
else
|
||||
{
|
||||
/* IPv6 */
|
||||
thisV6 = (os_sockaddr_in6*) addr1;
|
||||
thatV6 = (os_sockaddr_in6*) addr2;
|
||||
r = memcmp(&thisV6->sin6_addr.s6_addr, &thatV6->sin6_addr.s6_addr, sizeof(unsigned char) * 16);
|
||||
if (r == 0) {
|
||||
port1 = os_sockaddrGetPort(addr1);
|
||||
port2 = os_sockaddrGetPort(addr2);
|
||||
if (port1 == port2) {
|
||||
result = 0;
|
||||
} else {
|
||||
if (port1 > port2) {
|
||||
result = 1;
|
||||
} else {
|
||||
result = -1;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (r > 0) {
|
||||
result = 1;
|
||||
} else {
|
||||
result = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
return result;
|
||||
|
||||
return unspec;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -342,7 +292,7 @@ os_sockaddrIsLoopback(const os_sockaddr* thisSock)
|
|||
if (thisSock->sa_family == AF_INET6)
|
||||
{
|
||||
result = IN6_IS_ADDR_LOOPBACK(&((os_sockaddr_in6*)thisSock)->sin6_addr) ||
|
||||
os_sockaddrIPAddressEqual(thisSock, linkLocalLoopbackPtr) ? true : false;
|
||||
os_sockaddr_compare(thisSock, linkLocalLoopbackPtr) == 0 ? true : false;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
|
@ -354,38 +304,6 @@ os_sockaddrIsLoopback(const os_sockaddr* thisSock)
|
|||
return result;
|
||||
}
|
||||
|
||||
size_t
|
||||
os_sockaddrSizeof(
|
||||
const os_sockaddr* sa)
|
||||
{
|
||||
size_t result;
|
||||
assert(sa);
|
||||
switch(sa->sa_family){
|
||||
#if (OS_SOCKET_HAS_IPV6 == 1)
|
||||
case AF_INET6:
|
||||
result = sizeof(os_sockaddr_in6);
|
||||
break;
|
||||
#endif
|
||||
case AF_INET:
|
||||
result = sizeof(os_sockaddr_in);
|
||||
break;
|
||||
default:
|
||||
#if (OS_SOCKET_HAS_IPV6 == 1)
|
||||
OS_ERROR("os_sockaddrSizeof", 0,
|
||||
"Unkown address family specified: %d. Should be AF_INET (%d) or AF_INET6 (%d)",
|
||||
(int)sa->sa_family, AF_INET, AF_INET6);
|
||||
#else
|
||||
OS_ERROR("os_sockaddrSizeof", 0,
|
||||
"Unkown address family specified: %d. Should be AF_INET (%d)",
|
||||
(int)sa->sa_family, AF_INET);
|
||||
#endif
|
||||
result = 0;
|
||||
break;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
os_sockaddrSetInAddrAny(
|
||||
os_sockaddr* sa)
|
||||
|
@ -406,54 +324,6 @@ os_sockaddrSetInAddrAny(
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
os_sockaddrSetPort(
|
||||
os_sockaddr* sa,
|
||||
uint16_t port /* network byte order */)
|
||||
{
|
||||
assert(sa);
|
||||
#if (OS_SOCKET_HAS_IPV6 == 1)
|
||||
assert(sa->sa_family == AF_INET6 || sa->sa_family == AF_INET);
|
||||
if (sa->sa_family == AF_INET6)
|
||||
{
|
||||
((os_sockaddr_in6*)sa)->sin6_port = port;
|
||||
}
|
||||
else
|
||||
#else
|
||||
assert(sa->sa_family == AF_INET);
|
||||
#endif
|
||||
if (sa->sa_family == AF_INET)
|
||||
{
|
||||
((os_sockaddr_in*)sa)->sin_port = port;
|
||||
}
|
||||
}
|
||||
|
||||
uint16_t /* network byte order */
|
||||
os_sockaddrGetPort(
|
||||
const os_sockaddr* const sa)
|
||||
{
|
||||
uint16_t port = 0;
|
||||
assert(sa);
|
||||
#if (OS_SOCKET_HAS_IPV6 == 1)
|
||||
assert(sa->sa_family == AF_INET6 || sa->sa_family == AF_INET);
|
||||
if (sa->sa_family == AF_INET6)
|
||||
{
|
||||
port = (uint16_t)((os_sockaddr_in6*)sa)->sin6_port;
|
||||
}
|
||||
else
|
||||
#else
|
||||
assert(sa->sa_family == AF_INET);
|
||||
#endif
|
||||
if (sa->sa_family == AF_INET)
|
||||
{
|
||||
port = (uint16_t)((os_sockaddr_in*)sa)->sin_port;
|
||||
}
|
||||
|
||||
return port;
|
||||
}
|
||||
|
||||
|
||||
char*
|
||||
os_sockaddrAddressToString(const os_sockaddr* sa,
|
||||
char* buffer, size_t buflen)
|
||||
|
@ -478,34 +348,3 @@ os_sockaddrAddressToString(const os_sockaddr* sa,
|
|||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
char*
|
||||
os_sockaddrAddressPortToString(
|
||||
const os_sockaddr* sa,
|
||||
char* buffer,
|
||||
size_t buflen)
|
||||
{
|
||||
size_t pos;
|
||||
switch (sa->sa_family)
|
||||
{
|
||||
case AF_INET:
|
||||
os_sockaddrAddressToString (sa, buffer, buflen);
|
||||
pos = strlen (buffer);
|
||||
(void) snprintf (buffer + pos, buflen - pos, ":%hu", ntohs (((os_sockaddr_in *) sa)->sin_port));
|
||||
break;
|
||||
#if OS_SOCKET_HAS_IPV6
|
||||
case AF_INET6:
|
||||
if(buflen){
|
||||
buffer[0] = '[';
|
||||
os_sockaddrAddressToString (sa, buffer + 1, buflen - 1);
|
||||
pos = strlen (buffer);
|
||||
(void) snprintf (buffer + pos, buflen - pos, "]:%hu", ntohs (((os_sockaddr_in6 *) sa)->sin6_port));
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
(void) snprintf(buffer, buflen, "Unknown address family");
|
||||
break;
|
||||
}
|
||||
return buffer;
|
||||
}
|
||||
|
|
114
src/os/src/posix/os_platform_ifaddrs.c
Normal file
114
src/os/src/posix/os_platform_ifaddrs.c
Normal file
|
@ -0,0 +1,114 @@
|
|||
/*
|
||||
* Copyright(c) 2006 to 2018 ADLINK Technology Limited and others
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License v. 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
|
||||
* v. 1.0 which is available at
|
||||
* http://www.eclipse.org/org/documents/edl-v10.php.
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
|
||||
*/
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "os/os.h"
|
||||
|
||||
extern const int *const os_supp_afs;
|
||||
|
||||
static int
|
||||
copyaddr(os_ifaddrs_t **ifap, const struct ifaddrs *sys_ifa)
|
||||
{
|
||||
int err = 0;
|
||||
os_ifaddrs_t *ifa;
|
||||
size_t sz;
|
||||
|
||||
assert(ifap != NULL);
|
||||
assert(sys_ifa != NULL);
|
||||
|
||||
sz = os_sockaddr_get_size(sys_ifa->ifa_addr);
|
||||
ifa = os_calloc_s(1, sizeof(*ifa));
|
||||
if (ifa == NULL) {
|
||||
err = errno;
|
||||
} else {
|
||||
ifa->index = if_nametoindex(sys_ifa->ifa_name);
|
||||
ifa->flags = sys_ifa->ifa_flags;
|
||||
if ((ifa->name = os_strdup(sys_ifa->ifa_name)) == NULL ||
|
||||
(ifa->addr = os_memdup(sys_ifa->ifa_addr, sz)) == NULL ||
|
||||
(sys_ifa->ifa_netmask != NULL &&
|
||||
(ifa->netmask = os_memdup(sys_ifa->ifa_netmask, sz)) == NULL) ||
|
||||
(sys_ifa->ifa_broadaddr != NULL &&
|
||||
(sys_ifa->ifa_flags & IFF_BROADCAST) &&
|
||||
(ifa->broadaddr = os_memdup(sys_ifa->ifa_broadaddr, sz)) == NULL))
|
||||
{
|
||||
err = errno;
|
||||
}
|
||||
}
|
||||
|
||||
if (err == 0) {
|
||||
*ifap = ifa;
|
||||
} else {
|
||||
os_freeifaddrs(ifa);
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
_Success_(return == 0) int
|
||||
os_getifaddrs(
|
||||
_Inout_ os_ifaddrs_t **ifap,
|
||||
_In_opt_ const int *afs)
|
||||
{
|
||||
int err = 0;
|
||||
int use;
|
||||
os_ifaddrs_t *ifa, *ifa_root, *ifa_next;
|
||||
struct ifaddrs *sys_ifa, *sys_ifa_root;
|
||||
struct sockaddr *sa;
|
||||
|
||||
assert(ifap != NULL);
|
||||
|
||||
if (afs == NULL) {
|
||||
afs = os_supp_afs;
|
||||
}
|
||||
|
||||
if (getifaddrs(&sys_ifa_root) == -1) {
|
||||
err = errno;
|
||||
} else {
|
||||
ifa = ifa_root = NULL;
|
||||
|
||||
for (sys_ifa = sys_ifa_root;
|
||||
sys_ifa != NULL && err == 0;
|
||||
sys_ifa = sys_ifa->ifa_next)
|
||||
{
|
||||
sa = sys_ifa->ifa_addr;
|
||||
if (sa != NULL) {
|
||||
use = 0;
|
||||
for (int i = 0; !use && afs[i] != OS_AF_NULL; i++) {
|
||||
use = (sa->sa_family == afs[i]);
|
||||
}
|
||||
|
||||
if (use) {
|
||||
err = copyaddr(&ifa_next, sys_ifa);
|
||||
if (err == 0) {
|
||||
if (ifa == NULL) {
|
||||
ifa = ifa_root = ifa_next;
|
||||
} else {
|
||||
ifa->next = ifa_next;
|
||||
ifa = ifa_next;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
freeifaddrs(sys_ifa_root);
|
||||
|
||||
if (err == 0) {
|
||||
*ifap = ifa_root;
|
||||
} else {
|
||||
os_freeifaddrs(ifa_root);
|
||||
}
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
|
@ -230,98 +230,3 @@ os_sockSelect(
|
|||
|
||||
return r;
|
||||
}
|
||||
|
||||
_Check_return_
|
||||
static os_result
|
||||
os_queryInterfaceAttributesIPv4 (_In_ const struct ifaddrs *ifa, _Inout_ os_ifAttributes *ifElement)
|
||||
{
|
||||
os_result result = os_resultSuccess;
|
||||
strncpy (ifElement->name, ifa->ifa_name, OS_IFNAMESIZE);
|
||||
ifElement->name[OS_IFNAMESIZE - 1] = '\0';
|
||||
memcpy (&ifElement->address, ifa->ifa_addr, sizeof (os_sockaddr_in));
|
||||
ifElement->flags = ifa->ifa_flags;
|
||||
if (ifElement->flags & IFF_BROADCAST)
|
||||
memcpy (&ifElement->broadcast_address, ifa->ifa_broadaddr, sizeof (os_sockaddr_in));
|
||||
else
|
||||
memset (&ifElement->broadcast_address, 0, sizeof (ifElement->broadcast_address));
|
||||
memcpy (&ifElement->network_mask, ifa->ifa_netmask, sizeof (os_sockaddr_in));
|
||||
ifElement->interfaceIndexNo = (unsigned) if_nametoindex (ifa->ifa_name);
|
||||
return result;
|
||||
}
|
||||
|
||||
_Check_return_
|
||||
static os_result
|
||||
os_queryInterfaceAttributesIPv6 (_In_ const struct ifaddrs *ifa, _Inout_ os_ifAttributes *ifElement)
|
||||
{
|
||||
os_result result = os_resultSuccess;
|
||||
strncpy (ifElement->name, ifa->ifa_name, OS_IFNAMESIZE);
|
||||
ifElement->name[OS_IFNAMESIZE - 1] = '\0';
|
||||
memcpy (&ifElement->address, ifa->ifa_addr, sizeof (os_sockaddr_in6));
|
||||
ifElement->flags = ifa->ifa_flags;
|
||||
memset (&ifElement->broadcast_address, 0, sizeof (ifElement->broadcast_address));
|
||||
memset (&ifElement->network_mask, 0, sizeof (ifElement->network_mask));
|
||||
ifElement->interfaceIndexNo = (unsigned) if_nametoindex (ifa->ifa_name);
|
||||
return result;
|
||||
}
|
||||
|
||||
os_result os_sockQueryInterfaces (os_ifAttributes *ifList, uint32_t listSize, uint32_t *validElements)
|
||||
{
|
||||
os_result result = os_resultSuccess;
|
||||
unsigned int listIndex;
|
||||
struct ifaddrs *ifa_first, *ifa;
|
||||
if (getifaddrs (&ifa_first) != 0)
|
||||
{
|
||||
perror ("getifaddrs");
|
||||
return os_resultFail;
|
||||
}
|
||||
listIndex = 0;
|
||||
for (ifa = ifa_first; ifa && listIndex < listSize; ifa = ifa->ifa_next)
|
||||
{
|
||||
if (ifa->ifa_addr && ((struct sockaddr_in *) ifa->ifa_addr)->sin_family == AF_INET)
|
||||
{
|
||||
/* Get other interface attributes */
|
||||
result = os_queryInterfaceAttributesIPv4 (ifa, &ifList[listIndex]);
|
||||
if (result == os_resultSuccess)
|
||||
listIndex++;
|
||||
}
|
||||
|
||||
if (result == os_resultSuccess)
|
||||
*validElements = listIndex;
|
||||
}
|
||||
freeifaddrs (ifa_first);
|
||||
return result;
|
||||
}
|
||||
|
||||
os_result os_sockQueryIPv6Interfaces (os_ifAttributes *ifList, uint32_t listSize, uint32_t *validElements)
|
||||
{
|
||||
struct ifaddrs* interfaceList = NULL;
|
||||
struct ifaddrs* nextInterface = NULL;
|
||||
unsigned int listIndex = 0;
|
||||
|
||||
*validElements = 0;
|
||||
if (getifaddrs (&interfaceList) != 0)
|
||||
{
|
||||
return os_resultFail;
|
||||
}
|
||||
|
||||
nextInterface = interfaceList;
|
||||
while (nextInterface != NULL && listIndex < listSize)
|
||||
{
|
||||
if (nextInterface->ifa_addr && nextInterface->ifa_addr->sa_family == AF_INET6)
|
||||
{
|
||||
os_sockaddr_in6 *v6Address = (os_sockaddr_in6 *) nextInterface->ifa_addr;
|
||||
if (!IN6_IS_ADDR_UNSPECIFIED (&v6Address->sin6_addr))
|
||||
{
|
||||
os_result result = os_resultSuccess;
|
||||
result = os_queryInterfaceAttributesIPv6 (nextInterface, &ifList[listIndex]);
|
||||
if (result == os_resultSuccess)
|
||||
listIndex++;
|
||||
}
|
||||
}
|
||||
nextInterface = nextInterface->ifa_next;
|
||||
}
|
||||
*validElements = listIndex;
|
||||
freeifaddrs(interfaceList);
|
||||
return os_resultSuccess;
|
||||
}
|
||||
|
||||
|
|
|
@ -21,8 +21,13 @@
|
|||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
|
||||
|
||||
#include "os_stdlib_strsep.c"
|
||||
#include "os_stdlib_memdup.c"
|
||||
#include "os_stdlib_rindex.c"
|
||||
#include "os_stdlib_asprintf.c"
|
||||
#include "os_stdlib_strcasecmp.c"
|
||||
#include "os_stdlib_strncasecmp.c"
|
||||
#include "os_stdlib_strdup.c"
|
||||
|
||||
_Ret_opt_z_ const char *
|
||||
os_getenv(
|
||||
|
@ -79,38 +84,6 @@ os_access(
|
|||
return result;
|
||||
}
|
||||
|
||||
char *
|
||||
os_rindex(
|
||||
const char *s,
|
||||
int c)
|
||||
{
|
||||
char *last = NULL;
|
||||
|
||||
while (*s) {
|
||||
if (*s == c) {
|
||||
last = (char *)s;
|
||||
}
|
||||
s++;
|
||||
}
|
||||
return last;
|
||||
}
|
||||
|
||||
_Ret_z_
|
||||
_Check_return_
|
||||
char *
|
||||
os_strdup(
|
||||
_In_z_ const char *s1)
|
||||
{
|
||||
size_t len;
|
||||
char *dup;
|
||||
|
||||
len = strlen(s1) + 1;
|
||||
dup = os_malloc(len);
|
||||
memcpy(dup, s1, len);
|
||||
|
||||
return dup;
|
||||
}
|
||||
|
||||
int
|
||||
os_vsnprintf(
|
||||
char *str,
|
||||
|
@ -157,48 +130,6 @@ os_vfprintfnosigpipe(
|
|||
return result;
|
||||
}
|
||||
|
||||
int
|
||||
os_strcasecmp(
|
||||
const char *s1,
|
||||
const char *s2)
|
||||
{
|
||||
int cr;
|
||||
|
||||
while (*s1 && *s2) {
|
||||
cr = tolower(*s1) - tolower(*s2);
|
||||
if (cr) {
|
||||
return cr;
|
||||
}
|
||||
s1++;
|
||||
s2++;
|
||||
}
|
||||
cr = tolower(*s1) - tolower(*s2);
|
||||
return cr;
|
||||
}
|
||||
|
||||
int
|
||||
os_strncasecmp(
|
||||
const char *s1,
|
||||
const char *s2,
|
||||
size_t n)
|
||||
{
|
||||
int cr = 0;
|
||||
|
||||
while (*s1 && *s2 && n) {
|
||||
cr = tolower(*s1) - tolower(*s2);
|
||||
if (cr) {
|
||||
return cr;
|
||||
}
|
||||
s1++;
|
||||
s2++;
|
||||
n--;
|
||||
}
|
||||
if (n) {
|
||||
cr = tolower(*s1) - tolower(*s2);
|
||||
}
|
||||
return cr;
|
||||
}
|
||||
|
||||
os_result
|
||||
os_stat(
|
||||
const char *path,
|
||||
|
|
48
src/os/src/snippets/code/os_stdlib_asprintf.c
Normal file
48
src/os/src/snippets/code/os_stdlib_asprintf.c
Normal file
|
@ -0,0 +1,48 @@
|
|||
/*
|
||||
* Copyright(c) 2006 to 2018 ADLINK Technology Limited and others
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License v. 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
|
||||
* v. 1.0 which is available at
|
||||
* http://www.eclipse.org/org/documents/edl-v10.php.
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
|
||||
*/
|
||||
#include "os/os.h"
|
||||
|
||||
int
|
||||
os_asprintf(
|
||||
char **strp,
|
||||
const char *fmt,
|
||||
...)
|
||||
{
|
||||
int ret;
|
||||
unsigned int len;
|
||||
char buf[1] = { '\0' };
|
||||
char *str = NULL;
|
||||
va_list args1, args2;
|
||||
|
||||
assert(strp != NULL);
|
||||
assert(fmt != NULL);
|
||||
|
||||
va_start(args1, fmt);
|
||||
va_copy(args2, args1); /* va_list cannot be reused */
|
||||
|
||||
if ((ret = os_vsnprintf(buf, sizeof(buf), fmt, args1)) >= 0) {
|
||||
len = (unsigned int)ret; /* +1 for null byte */
|
||||
if ((str = os_malloc(len + 1)) == NULL) {
|
||||
ret = -1;
|
||||
} else if ((ret = os_vsnprintf(str, len + 1, fmt, args2)) >= 0) {
|
||||
assert(((unsigned int)ret) == len);
|
||||
*strp = str;
|
||||
} else {
|
||||
os_free(str);
|
||||
}
|
||||
}
|
||||
|
||||
va_end(args1);
|
||||
va_end(args2);
|
||||
|
||||
return ret;
|
||||
}
|
24
src/os/src/snippets/code/os_stdlib_memdup.c
Normal file
24
src/os/src/snippets/code/os_stdlib_memdup.c
Normal file
|
@ -0,0 +1,24 @@
|
|||
/*
|
||||
* Copyright(c) 2006 to 2018 ADLINK Technology Limited and others
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License v. 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
|
||||
* v. 1.0 which is available at
|
||||
* http://www.eclipse.org/org/documents/edl-v10.php.
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
|
||||
*/
|
||||
#include "os/os.h"
|
||||
|
||||
void *
|
||||
os_memdup(const void *src, size_t n)
|
||||
{
|
||||
void *dest = NULL;
|
||||
|
||||
if (n != 0 && (dest = os_malloc_s(n)) != NULL) {
|
||||
memcpy(dest, src, n);
|
||||
}
|
||||
|
||||
return dest;
|
||||
}
|
28
src/os/src/snippets/code/os_stdlib_rindex.c
Normal file
28
src/os/src/snippets/code/os_stdlib_rindex.c
Normal file
|
@ -0,0 +1,28 @@
|
|||
/*
|
||||
* Copyright(c) 2006 to 2018 ADLINK Technology Limited and others
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License v. 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
|
||||
* v. 1.0 which is available at
|
||||
* http://www.eclipse.org/org/documents/edl-v10.php.
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
|
||||
*/
|
||||
#include <stddef.h>
|
||||
|
||||
char *
|
||||
os_rindex(
|
||||
const char *s,
|
||||
int c)
|
||||
{
|
||||
char *last = NULL;
|
||||
|
||||
while (*s) {
|
||||
if (*s == c) {
|
||||
last = (char *)s;
|
||||
}
|
||||
s++;
|
||||
}
|
||||
return last;
|
||||
}
|
34
src/os/src/snippets/code/os_stdlib_strcasecmp.c
Normal file
34
src/os/src/snippets/code/os_stdlib_strcasecmp.c
Normal file
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
* Copyright(c) 2006 to 2018 ADLINK Technology Limited and others
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License v. 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
|
||||
* v. 1.0 which is available at
|
||||
* http://www.eclipse.org/org/documents/edl-v10.php.
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
|
||||
*/
|
||||
#include "os/os.h"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning( default : 4996 )
|
||||
#endif /* _MSC_VER */
|
||||
int
|
||||
os_strcasecmp(
|
||||
const char *s1,
|
||||
const char *s2)
|
||||
{
|
||||
int cr;
|
||||
|
||||
while (*s1 && *s2) {
|
||||
cr = tolower(*s1) - tolower(*s2);
|
||||
if (cr) {
|
||||
return cr;
|
||||
}
|
||||
s1++;
|
||||
s2++;
|
||||
}
|
||||
cr = tolower(*s1) - tolower(*s2);
|
||||
return cr;
|
||||
}
|
23
src/os/src/snippets/code/os_stdlib_strdup.c
Normal file
23
src/os/src/snippets/code/os_stdlib_strdup.c
Normal file
|
@ -0,0 +1,23 @@
|
|||
/*
|
||||
* Copyright(c) 2006 to 2018 ADLINK Technology Limited and others
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License v. 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
|
||||
* v. 1.0 which is available at
|
||||
* http://www.eclipse.org/org/documents/edl-v10.php.
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
|
||||
*/
|
||||
#include "os/os.h"
|
||||
|
||||
_Ret_z_
|
||||
_Check_return_
|
||||
char *
|
||||
os_strdup(
|
||||
_In_z_ const char *str)
|
||||
{
|
||||
assert(str != NULL);
|
||||
|
||||
return os_memdup(str, strlen(str) + 1);
|
||||
}
|
35
src/os/src/snippets/code/os_stdlib_strncasecmp.c
Normal file
35
src/os/src/snippets/code/os_stdlib_strncasecmp.c
Normal file
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
* Copyright(c) 2006 to 2018 ADLINK Technology Limited and others
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License v. 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
|
||||
* v. 1.0 which is available at
|
||||
* http://www.eclipse.org/org/documents/edl-v10.php.
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
|
||||
*/
|
||||
#include "os/os.h"
|
||||
|
||||
int
|
||||
os_strncasecmp(
|
||||
const char *s1,
|
||||
const char *s2,
|
||||
size_t n)
|
||||
{
|
||||
int cr = 0;
|
||||
|
||||
while (*s1 && *s2 && n) {
|
||||
cr = tolower(*s1) - tolower(*s2);
|
||||
if (cr) {
|
||||
return cr;
|
||||
}
|
||||
s1++;
|
||||
s2++;
|
||||
n--;
|
||||
}
|
||||
if (n) {
|
||||
cr = tolower(*s1) - tolower(*s2);
|
||||
}
|
||||
return cr;
|
||||
}
|
269
src/os/src/windows/os_platform_ifaddrs.c
Normal file
269
src/os/src/windows/os_platform_ifaddrs.c
Normal file
|
@ -0,0 +1,269 @@
|
|||
/*
|
||||
* Copyright(c) 2006 to 2018 ADLINK Technology Limited and others
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License v. 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
|
||||
* v. 1.0 which is available at
|
||||
* http://www.eclipse.org/org/documents/edl-v10.php.
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
|
||||
*/
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "os/os.h"
|
||||
|
||||
extern const int *const os_supp_afs;
|
||||
|
||||
static int
|
||||
getifaces(PIP_ADAPTER_ADDRESSES *ptr)
|
||||
{
|
||||
int err = ERANGE;
|
||||
PIP_ADAPTER_ADDRESSES buf = NULL;
|
||||
ULONG bufsz = 0; /* Size is determined on first iteration. */
|
||||
ULONG ret;
|
||||
size_t i;
|
||||
|
||||
static const size_t max = 2;
|
||||
static const ULONG filter = GAA_FLAG_INCLUDE_PREFIX |
|
||||
GAA_FLAG_SKIP_ANYCAST |
|
||||
GAA_FLAG_SKIP_MULTICAST |
|
||||
GAA_FLAG_SKIP_DNS_SERVER;
|
||||
|
||||
assert(ptr != NULL);
|
||||
|
||||
for (i = 0; err == ERANGE && i < max; i++) {
|
||||
ret = GetAdaptersAddresses(AF_UNSPEC, filter, NULL, buf, &bufsz);
|
||||
assert(ret != ERROR_INVALID_PARAMETER);
|
||||
switch (ret) {
|
||||
case ERROR_BUFFER_OVERFLOW:
|
||||
err = ERANGE;
|
||||
os_free(buf);
|
||||
if ((buf = (IP_ADAPTER_ADDRESSES *)os_malloc(bufsz)) == NULL) {
|
||||
err = ENOMEM;
|
||||
}
|
||||
break;
|
||||
case ERROR_NOT_ENOUGH_MEMORY:
|
||||
err = ENOMEM;
|
||||
break;
|
||||
case ERROR_SUCCESS:
|
||||
case ERROR_ADDRESS_NOT_ASSOCIATED: /* No address associated yet. */
|
||||
case ERROR_NO_DATA: /* No adapters that match the filter. */
|
||||
default:
|
||||
err = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (err == 0) {
|
||||
*ptr = buf;
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static int
|
||||
getaddrtable(PMIB_IPADDRTABLE *ptr)
|
||||
{
|
||||
int err = ERANGE;
|
||||
PMIB_IPADDRTABLE buf = NULL;
|
||||
ULONG bufsz = 0;
|
||||
DWORD ret;
|
||||
size_t i;
|
||||
|
||||
static const size_t max = 2;
|
||||
|
||||
assert(ptr != NULL);
|
||||
|
||||
for (i = 0; err == ERANGE && i < max; i++) {
|
||||
ret = GetIpAddrTable(buf, &bufsz, 0);
|
||||
assert(ret != ERROR_INVALID_PARAMETER &&
|
||||
ret != ERROR_NOT_SUPPORTED);
|
||||
switch (ret) {
|
||||
case ERROR_INSUFFICIENT_BUFFER:
|
||||
err = ERANGE;
|
||||
os_free(buf);
|
||||
if ((buf = (PMIB_IPADDRTABLE)os_malloc(bufsz)) == NULL) {
|
||||
err = ENOMEM;
|
||||
}
|
||||
break;
|
||||
case ERROR_SUCCESS:
|
||||
default:
|
||||
err = GetLastError();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (err == 0) {
|
||||
*ptr = buf;
|
||||
} else {
|
||||
os_free(buf);
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static uint32_t
|
||||
getflags(const PIP_ADAPTER_ADDRESSES iface)
|
||||
{
|
||||
uint32_t flags = 0;
|
||||
|
||||
if (iface->OperStatus == IfOperStatusUp) {
|
||||
flags |= IFF_UP;
|
||||
}
|
||||
if (iface->IfType == IF_TYPE_SOFTWARE_LOOPBACK) {
|
||||
flags |= IFF_LOOPBACK;
|
||||
}
|
||||
if (!(iface->Flags & IP_ADAPTER_NO_MULTICAST)) {
|
||||
flags |= IFF_MULTICAST;
|
||||
}
|
||||
|
||||
/* FIXME: Shouldn't IFF_LOOPBACK be included here? */
|
||||
switch (iface->IfType) {
|
||||
case IF_TYPE_ETHERNET_CSMACD:
|
||||
case IF_TYPE_IEEE80211:
|
||||
case IF_TYPE_IEEE1394:
|
||||
case IF_TYPE_ISO88025_TOKENRING:
|
||||
flags |= IFF_BROADCAST;
|
||||
break;
|
||||
default:
|
||||
flags |= IFF_POINTTOPOINT;
|
||||
break;
|
||||
}
|
||||
|
||||
return flags;
|
||||
}
|
||||
|
||||
static int
|
||||
copyaddr(
|
||||
os_ifaddrs_t **ifap,
|
||||
const PIP_ADAPTER_ADDRESSES iface,
|
||||
const PMIB_IPADDRTABLE addrtable,
|
||||
const PIP_ADAPTER_UNICAST_ADDRESS addr)
|
||||
{
|
||||
int err = 0;
|
||||
int eq = 0;
|
||||
os_ifaddrs_t *ifa;
|
||||
DWORD i;
|
||||
struct sockaddr *sa = (struct sockaddr *)addr->Address.lpSockaddr;
|
||||
size_t size;
|
||||
|
||||
assert(iface != NULL);
|
||||
assert(addrtable != NULL);
|
||||
assert(addr != NULL);
|
||||
|
||||
if ((ifa = os_calloc_s(1, sizeof(*ifa))) == NULL) {
|
||||
err = ENOMEM;
|
||||
} else {
|
||||
ifa->flags = getflags(iface);
|
||||
(void)os_asprintf(&ifa->name, "%wS", iface->FriendlyName);
|
||||
|
||||
if (ifa->name == NULL) {
|
||||
err = ENOMEM;
|
||||
} else {
|
||||
ifa->addr = os_memdup(sa, addr->Address.iSockaddrLength);
|
||||
if (ifa->addr == NULL) {
|
||||
err = ENOMEM;
|
||||
} else if (ifa->addr->sa_family == AF_INET) {
|
||||
size = sizeof(struct sockaddr_in);
|
||||
struct sockaddr_in netmask, broadaddr;
|
||||
|
||||
memset(&netmask, 0, size);
|
||||
memset(&broadaddr, 0, size);
|
||||
netmask.sin_family = broadaddr.sin_family = AF_INET;
|
||||
|
||||
for (i = 0; !eq && i < addrtable->dwNumEntries; i++) {
|
||||
eq = (((struct sockaddr_in *)sa)->sin_addr.s_addr ==
|
||||
addrtable->table[i].dwAddr);
|
||||
if (eq) {
|
||||
ifa->index = addrtable->table[i].dwIndex;
|
||||
netmask.sin_addr.s_addr = addrtable->table[i].dwMask;
|
||||
broadaddr.sin_addr.s_addr =
|
||||
((struct sockaddr_in *)sa)->sin_addr.s_addr | ~(netmask.sin_addr.s_addr);
|
||||
}
|
||||
}
|
||||
|
||||
assert(eq != 0);
|
||||
|
||||
if ((ifa->netmask = os_memdup(&netmask, size)) == NULL ||
|
||||
(ifa->broadaddr = os_memdup(&broadaddr, size)) == NULL)
|
||||
{
|
||||
err = ENOMEM;
|
||||
}
|
||||
} else {
|
||||
ifa->index = iface->Ipv6IfIndex;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (err == 0) {
|
||||
*ifap = ifa;
|
||||
} else {
|
||||
os_free(ifa);
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
_Success_(return == 0) int
|
||||
os_getifaddrs(
|
||||
_Inout_ os_ifaddrs_t **ifap,
|
||||
_In_opt_ const int *afs)
|
||||
{
|
||||
int err = 0;
|
||||
int use;
|
||||
PIP_ADAPTER_ADDRESSES ifaces = NULL, iface;
|
||||
PIP_ADAPTER_UNICAST_ADDRESS addr = NULL;
|
||||
PMIB_IPADDRTABLE addrtable = NULL;
|
||||
os_ifaddrs_t *ifa, *ifa_root, *ifa_next;
|
||||
struct sockaddr *sa;
|
||||
|
||||
assert(ifap != NULL);
|
||||
|
||||
if (afs == NULL) {
|
||||
afs = os_supp_afs;
|
||||
}
|
||||
|
||||
ifa = ifa_root = ifa_next = NULL;
|
||||
|
||||
if ((err = getifaces(&ifaces)) == 0 &&
|
||||
(err = getaddrtable(&addrtable)) == 0)
|
||||
{
|
||||
for (iface = ifaces; !err && iface != NULL; iface = iface->Next) {
|
||||
for (addr = iface->FirstUnicastAddress;
|
||||
addr != NULL;
|
||||
addr = addr->Next)
|
||||
{
|
||||
sa = (struct sockaddr *)addr->Address.lpSockaddr;
|
||||
use = 0;
|
||||
for (int i = 0; !use && afs[i] != OS_AF_NULL; i++) {
|
||||
use = (afs[i] == sa->sa_family);
|
||||
}
|
||||
|
||||
if (use) {
|
||||
err = copyaddr(&ifa_next, iface, addrtable, addr);
|
||||
if (err == 0) {
|
||||
if (ifa == NULL) {
|
||||
ifa = ifa_root = ifa_next;
|
||||
} else {
|
||||
ifa->next = ifa_next;
|
||||
ifa = ifa_next;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
os_free(ifaces);
|
||||
os_free(addrtable);
|
||||
|
||||
if (err == 0) {
|
||||
*ifap = ifa_root;
|
||||
} else {
|
||||
os_freeifaddrs(ifa_root);
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
|
@ -19,9 +19,6 @@
|
|||
|
||||
#include <assert.h>
|
||||
|
||||
#define WORKING_BUFFER_SIZE 15000
|
||||
#define MAX_TRIES 3
|
||||
|
||||
typedef BOOL (WINAPI *qwaveQOSCreateHandleFuncT) (_In_ PQOS_VERSION Version, _Out_ PHANDLE QOSHandle);
|
||||
typedef BOOL (WINAPI *qwaveQOSCloseHandleFuncT) (_In_ HANDLE QOSHandle);
|
||||
typedef BOOL (WINAPI *qwaveQOSAddSocketToFlowFuncT) (
|
||||
|
@ -558,341 +555,3 @@ os__sockSelect(
|
|||
return r;
|
||||
}
|
||||
|
||||
static unsigned int
|
||||
getInterfaceFlags(PIP_ADAPTER_ADDRESSES pAddr)
|
||||
{
|
||||
unsigned int flags = 0;
|
||||
|
||||
if (pAddr->OperStatus == IfOperStatusUp) {
|
||||
flags |= IFF_UP;
|
||||
}
|
||||
|
||||
if (pAddr->IfType == IF_TYPE_SOFTWARE_LOOPBACK) {
|
||||
flags |= IFF_LOOPBACK;
|
||||
}
|
||||
|
||||
if (!(pAddr->Flags & IP_ADAPTER_NO_MULTICAST)) {
|
||||
flags |= IFF_MULTICAST;
|
||||
}
|
||||
|
||||
switch (pAddr->IfType) {
|
||||
case IF_TYPE_ETHERNET_CSMACD:
|
||||
case IF_TYPE_IEEE80211:
|
||||
case IF_TYPE_IEEE1394:
|
||||
case IF_TYPE_ISO88025_TOKENRING:
|
||||
flags |= IFF_BROADCAST;
|
||||
break;
|
||||
default:
|
||||
flags |= IFF_POINTTOPOINT;
|
||||
break;
|
||||
}
|
||||
|
||||
return flags;
|
||||
}
|
||||
|
||||
static os_result
|
||||
addressToIndexAndMask(struct sockaddr *addr, unsigned int *ifIndex, struct sockaddr *mask )
|
||||
{
|
||||
os_result result = os_resultSuccess;
|
||||
bool found = FALSE;
|
||||
PMIB_IPADDRTABLE pIPAddrTable = NULL;
|
||||
DWORD dwSize = 0;
|
||||
DWORD i;
|
||||
int errNo;
|
||||
|
||||
if (GetIpAddrTable(pIPAddrTable, &dwSize, 0) == ERROR_INSUFFICIENT_BUFFER) {
|
||||
pIPAddrTable = (MIB_IPADDRTABLE *) os_malloc(dwSize);
|
||||
if (pIPAddrTable != NULL) {
|
||||
if (GetIpAddrTable(pIPAddrTable, &dwSize, 0) != NO_ERROR) {
|
||||
errNo = os_getErrno();
|
||||
OS_ERROR("addressToIndexAndMask", 0, "GetIpAddrTable failed: %d", errNo);
|
||||
result = os_resultFail;
|
||||
}
|
||||
} else {
|
||||
OS_ERROR("addressToIndexAndMask", 0, "Failed to allocate %lu bytes for IP address table", dwSize);
|
||||
result = os_resultFail;
|
||||
}
|
||||
} else {
|
||||
errNo = os_getErrno();
|
||||
OS_ERROR("addressToIndexAndMask", 0, "GetIpAddrTable failed: %d", errNo);
|
||||
result = os_resultFail;
|
||||
}
|
||||
|
||||
if (result == os_resultSuccess) {
|
||||
for (i = 0; !found && i < pIPAddrTable->dwNumEntries; i++ ) {
|
||||
if (((struct sockaddr_in* ) addr )->sin_addr.s_addr == pIPAddrTable->table[i].dwAddr) {
|
||||
*ifIndex = pIPAddrTable->table[i].dwIndex;
|
||||
((struct sockaddr_in*) mask)->sin_addr.s_addr= pIPAddrTable->table[i].dwMask;
|
||||
found = TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (pIPAddrTable) {
|
||||
os_free(pIPAddrTable);
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
result = os_resultFail;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#define MAX_INTERFACES 64
|
||||
#define INTF_MAX_NAME_LEN 16
|
||||
|
||||
os_result
|
||||
os_sockQueryInterfaces(
|
||||
os_ifAttributes *ifList,
|
||||
unsigned int listSize,
|
||||
unsigned int *validElements)
|
||||
{
|
||||
os_result result = os_resultSuccess;
|
||||
DWORD filter;
|
||||
PIP_ADAPTER_ADDRESSES pAddresses = NULL;
|
||||
PIP_ADAPTER_ADDRESSES pCurrAddress = NULL;
|
||||
PIP_ADAPTER_UNICAST_ADDRESS pUnicast = NULL;
|
||||
unsigned long outBufLen = WORKING_BUFFER_SIZE;
|
||||
int retVal;
|
||||
int iterations = 0;
|
||||
int listIndex = 0;
|
||||
|
||||
filter = GAA_FLAG_INCLUDE_PREFIX | GAA_FLAG_SKIP_ANYCAST | GAA_FLAG_SKIP_MULTICAST | GAA_FLAG_SKIP_DNS_SERVER;
|
||||
|
||||
do {
|
||||
pAddresses = (IP_ADAPTER_ADDRESSES *) os_malloc(outBufLen);
|
||||
if (!pAddresses) {
|
||||
OS_ERROR("os_sockQueryInterfaces", 0, "Failed to allocate %lu bytes for Adapter addresses", outBufLen);
|
||||
return os_resultFail;
|
||||
}
|
||||
retVal = GetAdaptersAddresses(AF_INET, filter, NULL, pAddresses, &outBufLen);
|
||||
if (retVal == ERROR_BUFFER_OVERFLOW) {
|
||||
os_free(pAddresses);
|
||||
pAddresses = NULL;
|
||||
outBufLen <<= 1; /* double the buffer just to be save.*/
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
iterations++;
|
||||
} while ((retVal == ERROR_BUFFER_OVERFLOW) && (iterations < MAX_TRIES));
|
||||
|
||||
if (retVal != ERROR_SUCCESS) {
|
||||
if (pAddresses) {
|
||||
os_free(pAddresses);
|
||||
pAddresses = NULL;
|
||||
}
|
||||
OS_ERROR("os_sockQueryInterfaces", 0, "Failed to GetAdaptersAddresses");
|
||||
return os_resultFail;
|
||||
}
|
||||
|
||||
for (pCurrAddress = pAddresses; pCurrAddress; pCurrAddress = pCurrAddress->Next) {
|
||||
IP_ADAPTER_PREFIX *firstPrefix = NULL;
|
||||
|
||||
if (pCurrAddress->Length >= sizeof(IP_ADAPTER_ADDRESSES)) {
|
||||
firstPrefix = pCurrAddress->FirstPrefix;
|
||||
}
|
||||
|
||||
if (pCurrAddress->OperStatus != IfOperStatusUp) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (pUnicast = pCurrAddress->FirstUnicastAddress; pUnicast; pUnicast = pUnicast->Next) {
|
||||
unsigned int ipv4Index;
|
||||
struct sockaddr_in ipv4Netmask;
|
||||
|
||||
if (pUnicast->Address.lpSockaddr->sa_family != AF_INET) {
|
||||
continue;
|
||||
}
|
||||
|
||||
ipv4Index = 0;
|
||||
memset(&ipv4Netmask, 0, sizeof(ipv4Netmask));
|
||||
if (addressToIndexAndMask((struct sockaddr *) pUnicast->Address.lpSockaddr,
|
||||
&ipv4Index, (struct sockaddr *) &ipv4Netmask) != os_resultSuccess) {
|
||||
continue;
|
||||
}
|
||||
|
||||
(void)snprintf(ifList[listIndex].name, OS_IFNAMESIZE, "%wS", pCurrAddress->FriendlyName);
|
||||
|
||||
/* Get interface flags. */
|
||||
ifList[listIndex].flags = getInterfaceFlags(pCurrAddress);
|
||||
ifList[listIndex].interfaceIndexNo = ipv4Index;
|
||||
|
||||
memcpy(&ifList[listIndex].address, pUnicast->Address.lpSockaddr, pUnicast->Address.iSockaddrLength);
|
||||
memcpy(&ifList[listIndex].broadcast_address, pUnicast->Address.lpSockaddr, pUnicast->Address.iSockaddrLength);
|
||||
memcpy(&ifList[listIndex].network_mask, pUnicast->Address.lpSockaddr, pUnicast->Address.iSockaddrLength);
|
||||
|
||||
((struct sockaddr_in *)(&(ifList[listIndex].broadcast_address)))->sin_addr.s_addr =
|
||||
((struct sockaddr_in *)(&(ifList[listIndex].address)))->sin_addr.s_addr | ~(ipv4Netmask.sin_addr.s_addr);
|
||||
((struct sockaddr_in *)&(ifList[listIndex].network_mask))->sin_addr.s_addr = ipv4Netmask.sin_addr.s_addr;
|
||||
|
||||
listIndex++;
|
||||
}
|
||||
}
|
||||
|
||||
for (pCurrAddress = pAddresses; pCurrAddress; pCurrAddress = pCurrAddress->Next) {
|
||||
if (pCurrAddress->OperStatus != IfOperStatusUp) {
|
||||
(void)snprintf(ifList[listIndex].name, OS_IFNAMESIZE, "%wS", pCurrAddress->FriendlyName);
|
||||
|
||||
/* Get interface flags. */
|
||||
ifList[listIndex].flags = getInterfaceFlags(pCurrAddress);
|
||||
ifList[listIndex].interfaceIndexNo = 0;
|
||||
memset (&ifList[listIndex].address, 0, sizeof(ifList[listIndex].address));
|
||||
memset (&ifList[listIndex].broadcast_address, 0, sizeof (ifList[listIndex].broadcast_address));
|
||||
memset (&ifList[listIndex].network_mask, 0, sizeof (ifList[listIndex].network_mask));
|
||||
|
||||
listIndex++;
|
||||
}
|
||||
}
|
||||
|
||||
if (pAddresses) {
|
||||
os_free(pAddresses);
|
||||
}
|
||||
|
||||
*validElements = listIndex;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
os_result
|
||||
os_sockQueryIPv6Interfaces (
|
||||
os_ifAttributes *ifList,
|
||||
unsigned int listSize,
|
||||
unsigned int *validElements)
|
||||
{
|
||||
os_result result = os_resultSuccess;
|
||||
ULONG filter;
|
||||
PIP_ADAPTER_ADDRESSES pAddresses = NULL;
|
||||
PIP_ADAPTER_ADDRESSES pCurrAddress = NULL;
|
||||
PIP_ADAPTER_UNICAST_ADDRESS pUnicast = NULL;
|
||||
ULONG outBufLen = WORKING_BUFFER_SIZE;
|
||||
ULONG retVal;
|
||||
int iterations = 0;
|
||||
int listIndex = 0;
|
||||
|
||||
filter = GAA_FLAG_INCLUDE_PREFIX | GAA_FLAG_SKIP_ANYCAST | GAA_FLAG_SKIP_MULTICAST | GAA_FLAG_SKIP_DNS_SERVER;
|
||||
|
||||
do {
|
||||
pAddresses = (IP_ADAPTER_ADDRESSES *) os_malloc(outBufLen);
|
||||
if (!pAddresses) {
|
||||
OS_ERROR("os_sockQueryIPv6Interfaces", 0, "Failed to allocate %lu bytes for Adapter addresses", outBufLen);
|
||||
return os_resultFail;
|
||||
}
|
||||
retVal = GetAdaptersAddresses(AF_INET6, filter, NULL, pAddresses, &outBufLen);
|
||||
if (retVal == ERROR_BUFFER_OVERFLOW) {
|
||||
os_free(pAddresses);
|
||||
pAddresses = NULL;
|
||||
outBufLen <<= 1; /* double the buffer just to be save.*/
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
iterations++;
|
||||
} while ((retVal == ERROR_BUFFER_OVERFLOW) && (iterations < MAX_TRIES));
|
||||
|
||||
if (retVal != ERROR_SUCCESS) {
|
||||
if (pAddresses) {
|
||||
os_free(pAddresses);
|
||||
pAddresses = NULL;
|
||||
}
|
||||
OS_ERROR("os_sockQueryIPv6Interfaces", 0, "Failed to GetAdaptersAddresses");
|
||||
return os_resultFail;
|
||||
}
|
||||
|
||||
for (pCurrAddress = pAddresses; pCurrAddress; pCurrAddress = pCurrAddress->Next) {
|
||||
DWORD ipv6IfIndex = 0;
|
||||
IP_ADAPTER_PREFIX *firstPrefix = NULL;
|
||||
|
||||
if (pCurrAddress->Length >= sizeof(IP_ADAPTER_ADDRESSES)) {
|
||||
ipv6IfIndex = pCurrAddress->Ipv6IfIndex;
|
||||
firstPrefix = pCurrAddress->FirstPrefix;
|
||||
}
|
||||
|
||||
if (((ipv6IfIndex == 1) && (pCurrAddress->IfType != IF_TYPE_SOFTWARE_LOOPBACK)) || (pCurrAddress->IfType == IF_TYPE_TUNNEL)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (pCurrAddress->OperStatus != IfOperStatusUp) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (pUnicast = pCurrAddress->FirstUnicastAddress; pUnicast; pUnicast = pUnicast->Next) {
|
||||
IP_ADAPTER_PREFIX *prefix;
|
||||
IN6_ADDR mask;
|
||||
struct sockaddr_in6 *sa6;
|
||||
struct sockaddr_in6 ipv6Netmask;
|
||||
|
||||
if (pUnicast->Address.lpSockaddr->sa_family != AF_INET6) {
|
||||
continue;
|
||||
}
|
||||
|
||||
(void)snprintf(ifList[listIndex].name, OS_IFNAMESIZE, "%wS", pCurrAddress->FriendlyName);
|
||||
|
||||
/* Get interface flags. */
|
||||
ifList[listIndex].flags = getInterfaceFlags(pCurrAddress);
|
||||
ifList[listIndex].interfaceIndexNo = (uint32_t) pCurrAddress->Ipv6IfIndex;
|
||||
|
||||
memcpy(&ifList[listIndex].address, pUnicast->Address.lpSockaddr, pUnicast->Address.iSockaddrLength);
|
||||
memcpy(&ifList[listIndex].broadcast_address, pUnicast->Address.lpSockaddr, pUnicast->Address.iSockaddrLength);
|
||||
memcpy(&ifList[listIndex].network_mask, pUnicast->Address.lpSockaddr, pUnicast->Address.iSockaddrLength);
|
||||
|
||||
sa6 = (struct sockaddr_in6 *)&ifList[listIndex].network_mask;
|
||||
memset(&sa6->sin6_addr.s6_addr, 0xFF, sizeof(sa6->sin6_addr.s6_addr));
|
||||
|
||||
for (prefix = firstPrefix; prefix; prefix = prefix->Next) {
|
||||
unsigned int l, i;
|
||||
if ((prefix->PrefixLength == 0) || (prefix->PrefixLength > 128) ||
|
||||
(pUnicast->Address.iSockaddrLength != prefix->Address.iSockaddrLength) ||
|
||||
(memcmp(pUnicast->Address.lpSockaddr, prefix->Address.lpSockaddr, pUnicast->Address.iSockaddrLength) == 0)){
|
||||
continue;
|
||||
}
|
||||
|
||||
memset(&ipv6Netmask, 0, sizeof(ipv6Netmask));
|
||||
ipv6Netmask.sin6_family = AF_INET6;
|
||||
|
||||
l = prefix->PrefixLength;
|
||||
for (i = 0; l > 0; l -= 8, i++) {
|
||||
ipv6Netmask.sin6_addr.s6_addr[i] = (l >= 8) ? 0xFF : ((0xFF << (8-l)) & 0xFF);
|
||||
}
|
||||
|
||||
for (i = 0; i < 16; i++) {
|
||||
mask.s6_addr[i] =
|
||||
((struct sockaddr_in6 *)pUnicast->Address.lpSockaddr)->sin6_addr.s6_addr[i] & ipv6Netmask.sin6_addr.s6_addr[i];
|
||||
}
|
||||
|
||||
if (memcmp(((struct sockaddr_in6 *)prefix->Address.lpSockaddr)->sin6_addr.s6_addr,
|
||||
mask.s6_addr, sizeof(ipv6Netmask.sin6_addr)) == 0) {
|
||||
memcpy(&sa6->sin6_addr.s6_addr, &ipv6Netmask.sin6_addr.s6_addr, sizeof(sa6->sin6_addr.s6_addr));
|
||||
}
|
||||
}
|
||||
listIndex++;
|
||||
}
|
||||
}
|
||||
|
||||
for (pCurrAddress = pAddresses; pCurrAddress; pCurrAddress = pCurrAddress->Next) {
|
||||
if (pCurrAddress->OperStatus != IfOperStatusUp) {
|
||||
(void) snprintf(ifList[listIndex].name, OS_IFNAMESIZE, "%wS", pCurrAddress->FriendlyName);
|
||||
|
||||
/* Get interface flags. */
|
||||
ifList[listIndex].flags = getInterfaceFlags(pCurrAddress);
|
||||
ifList[listIndex].interfaceIndexNo = 0;
|
||||
memset (&ifList[listIndex].address, 0, sizeof(ifList[listIndex].address));
|
||||
memset (&ifList[listIndex].broadcast_address, 0, sizeof (ifList[listIndex].broadcast_address));
|
||||
memset (&ifList[listIndex].network_mask, 0, sizeof (ifList[listIndex].network_mask));
|
||||
|
||||
listIndex++;
|
||||
}
|
||||
}
|
||||
|
||||
if (pAddresses) {
|
||||
os_free(pAddresses);
|
||||
}
|
||||
|
||||
*validElements = listIndex;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
#undef MAX_INTERFACES
|
||||
|
|
|
@ -18,7 +18,13 @@
|
|||
#include "../snippets/code/os_stdlib_strtod.c"
|
||||
#include "../snippets/code/os_stdlib_strtol.c"
|
||||
#include "../snippets/code/os_stdlib_strtok_r.c"
|
||||
|
||||
#include "../snippets/code/os_stdlib_strsep.c"
|
||||
#include "../snippets/code/os_stdlib_strdup.c"
|
||||
#include "../snippets/code/os_stdlib_memdup.c"
|
||||
#include "../snippets/code/os_stdlib_asprintf.c"
|
||||
#include "../snippets/code/os_stdlib_rindex.c"
|
||||
#include "../snippets/code/os_stdlib_strcasecmp.c"
|
||||
#include "../snippets/code/os_stdlib_strncasecmp.c"
|
||||
|
||||
static int32_t
|
||||
os__ensurePathExists(
|
||||
|
@ -140,55 +146,6 @@ os_access(
|
|||
return result;
|
||||
}
|
||||
|
||||
char *
|
||||
os_rindex(
|
||||
const char *s,
|
||||
int c)
|
||||
{
|
||||
char *last = NULL;
|
||||
|
||||
while (*s) {
|
||||
if (*s == c) {
|
||||
last = (char *)s;
|
||||
}
|
||||
s++;
|
||||
}
|
||||
return last;
|
||||
}
|
||||
|
||||
_Ret_z_
|
||||
_Check_return_
|
||||
char *
|
||||
os_strdup(
|
||||
_In_z_ const char *s1)
|
||||
{
|
||||
size_t len;
|
||||
char *dup;
|
||||
|
||||
len = strlen(s1) + 1;
|
||||
dup = os_malloc(len);
|
||||
memcpy(dup, s1, len);
|
||||
|
||||
return dup;
|
||||
}
|
||||
|
||||
char *
|
||||
os_strsep(char **str, const char *sep)
|
||||
{
|
||||
char *ret;
|
||||
if (**str == '\0')
|
||||
return 0;
|
||||
ret = *str;
|
||||
while (**str && strchr(sep, **str) == 0)
|
||||
(*str)++;
|
||||
if (**str != '\0')
|
||||
{
|
||||
**str = '\0';
|
||||
(*str)++;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
#pragma warning( disable : 4996 )
|
||||
int
|
||||
os_vfprintfnosigpipe(
|
||||
|
@ -199,49 +156,6 @@ os_vfprintfnosigpipe(
|
|||
return vfprintf(file, format, args);
|
||||
}
|
||||
|
||||
#pragma warning( default : 4996 )
|
||||
int
|
||||
os_strcasecmp(
|
||||
const char *s1,
|
||||
const char *s2)
|
||||
{
|
||||
int cr;
|
||||
|
||||
while (*s1 && *s2) {
|
||||
cr = tolower(*s1) - tolower(*s2);
|
||||
if (cr) {
|
||||
return cr;
|
||||
}
|
||||
s1++;
|
||||
s2++;
|
||||
}
|
||||
cr = tolower(*s1) - tolower(*s2);
|
||||
return cr;
|
||||
}
|
||||
|
||||
int
|
||||
os_strncasecmp(
|
||||
const char *s1,
|
||||
const char *s2,
|
||||
size_t n)
|
||||
{
|
||||
int cr = 0;
|
||||
|
||||
while (*s1 && *s2 && n) {
|
||||
cr = tolower(*s1) - tolower(*s2);
|
||||
if (cr) {
|
||||
return cr;
|
||||
}
|
||||
s1++;
|
||||
s2++;
|
||||
n--;
|
||||
}
|
||||
if (n) {
|
||||
cr = tolower(*s1) - tolower(*s2);
|
||||
}
|
||||
return cr;
|
||||
}
|
||||
|
||||
os_result
|
||||
os_stat(
|
||||
const char *path,
|
||||
|
|
190
src/os/tests/ifaddrs.c
Normal file
190
src/os/tests/ifaddrs.c
Normal file
|
@ -0,0 +1,190 @@
|
|||
/*
|
||||
* Copyright(c) 2006 to 2018 ADLINK Technology Limited and others
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License v. 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
|
||||
* v. 1.0 which is available at
|
||||
* http://www.eclipse.org/org/documents/edl-v10.php.
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
|
||||
*/
|
||||
#include "CUnit/Runner.h"
|
||||
#include "os/os.h"
|
||||
|
||||
/* FIXME: It's not possible to predict what network interfaces are available
|
||||
on a given host. To properly test all combinations the abstracted
|
||||
operating system functions must be mocked. */
|
||||
|
||||
/* FIXME: It's possible that IPv6 is available in the network stack, but
|
||||
disabled in the kernel. Travis CI for example has build environments
|
||||
that do not have IPv6 enabled. */
|
||||
|
||||
#ifdef OS_SOCKET_HAS_IPV6
|
||||
static int ipv6_enabled = 1;
|
||||
#endif
|
||||
|
||||
CUnit_Suite_Initialize(os_getifaddrs)
|
||||
{
|
||||
os_osInit();
|
||||
|
||||
#ifdef OS_SOCKET_HAS_IPV6
|
||||
#ifdef __linux
|
||||
FILE *fh;
|
||||
const char *const *path;
|
||||
static const char *const paths[] = {
|
||||
"/proc/sys/net/ipv6/conf/all/disable_ipv6",
|
||||
"/proc/sys/net/ipv6/conf/default/disable_ipv6",
|
||||
NULL
|
||||
};
|
||||
|
||||
for (path = paths; ipv6_enabled == 1 && *path != NULL; path++) {
|
||||
if ((fh = fopen(*path, "r")) != NULL) {
|
||||
ipv6_enabled = (fgetc(fh) == '0');
|
||||
fclose(fh);
|
||||
fh = NULL;
|
||||
}
|
||||
}
|
||||
#endif /* __linux */
|
||||
#endif /* OS_SOCKET_HAS_IPV6 */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
CUnit_Suite_Cleanup(os_getifaddrs)
|
||||
{
|
||||
os_osExit();
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Assume every test machine has at least one IPv4 enabled interface. This
|
||||
simple test verifies an interface can at least be found and that the
|
||||
IFF_LOOPBACK flags are properly set. */
|
||||
CUnit_Test(os_getifaddrs, ipv4)
|
||||
{
|
||||
int err;
|
||||
int seen = 0;
|
||||
os_ifaddrs_t *ifa_root, *ifa;
|
||||
const int afs[] = { AF_INET, OS_AF_NULL };
|
||||
|
||||
err = os_getifaddrs(&ifa_root, afs);
|
||||
CU_ASSERT_EQUAL_FATAL(err, 0);
|
||||
for (ifa = ifa_root; ifa; ifa = ifa->next) {
|
||||
CU_ASSERT_PTR_NOT_EQUAL_FATAL(ifa->addr, NULL);
|
||||
CU_ASSERT_EQUAL(ifa->addr->sa_family, AF_INET);
|
||||
if (ifa->addr->sa_family == AF_INET) {
|
||||
if (ifa->flags & IFF_LOOPBACK) {
|
||||
CU_ASSERT(os_sockaddrIsLoopback(ifa->addr));
|
||||
} else {
|
||||
CU_ASSERT(!os_sockaddrIsLoopback(ifa->addr));
|
||||
}
|
||||
seen = 1;
|
||||
}
|
||||
}
|
||||
|
||||
CU_ASSERT_EQUAL(seen, 1);
|
||||
|
||||
os_freeifaddrs(ifa_root);
|
||||
}
|
||||
|
||||
CUnit_Test(os_getifaddrs, null_filter)
|
||||
{
|
||||
int err;
|
||||
int cnt = 0;
|
||||
os_ifaddrs_t *ifa_root, *ifa;
|
||||
|
||||
err = os_getifaddrs(&ifa_root, NULL);
|
||||
CU_ASSERT_EQUAL_FATAL(err, 0);
|
||||
for (ifa = ifa_root; ifa; ifa = ifa->next) {
|
||||
CU_ASSERT_PTR_NOT_EQUAL_FATAL(ifa->addr, NULL);
|
||||
cnt++;
|
||||
}
|
||||
|
||||
CU_ASSERT(cnt > 0);
|
||||
|
||||
os_freeifaddrs(ifa_root);
|
||||
}
|
||||
|
||||
CUnit_Test(os_getifaddrs, empty_filter)
|
||||
{
|
||||
int err;
|
||||
os_ifaddrs_t *ifa_root;
|
||||
const int afs[] = { OS_AF_NULL };
|
||||
|
||||
err = os_getifaddrs(&ifa_root, afs);
|
||||
CU_ASSERT_EQUAL_FATAL(err, 0);
|
||||
CU_ASSERT_PTR_EQUAL(ifa_root, NULL);
|
||||
|
||||
os_freeifaddrs(ifa_root);
|
||||
}
|
||||
|
||||
#ifdef OS_SOCKET_HAS_IPV6
|
||||
CUnit_Test(os_getifaddrs, ipv6)
|
||||
{
|
||||
if (ipv6_enabled == 1) {
|
||||
int err;
|
||||
int have_ipv6 = 0;
|
||||
os_ifaddrs_t *ifa_root, *ifa;
|
||||
const int afs[] = { AF_INET6, OS_AF_NULL };
|
||||
|
||||
err = os_getifaddrs(&ifa_root, afs);
|
||||
CU_ASSERT_EQUAL_FATAL(err, 0);
|
||||
for (ifa = ifa_root; ifa; ifa = ifa->next) {
|
||||
CU_ASSERT_PTR_NOT_EQUAL_FATAL(ifa->addr, NULL);
|
||||
CU_ASSERT_EQUAL(ifa->addr->sa_family, AF_INET6);
|
||||
if (ifa->addr->sa_family == AF_INET6) {
|
||||
have_ipv6 = 1;
|
||||
if (ifa->flags & IFF_LOOPBACK) {
|
||||
CU_ASSERT(os_sockaddrIsLoopback(ifa->addr));
|
||||
} else {
|
||||
CU_ASSERT(!os_sockaddrIsLoopback(ifa->addr));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CU_ASSERT_EQUAL(have_ipv6, 1);
|
||||
|
||||
os_freeifaddrs(ifa_root);
|
||||
|
||||
CU_PASS("IPv6 enabled in test environment");
|
||||
} else {
|
||||
CU_PASS("IPv6 disabled in test environment");
|
||||
}
|
||||
}
|
||||
|
||||
/* Assume at least one IPv4 and one IPv6 interface are available when IPv6 is
|
||||
available on the platform. */
|
||||
CUnit_Test(os_getifaddrs, ipv4_n_ipv6)
|
||||
{
|
||||
if (ipv6_enabled == 1) {
|
||||
int err;
|
||||
int have_ipv4 = 0;
|
||||
int have_ipv6 = 0;
|
||||
os_ifaddrs_t *ifa_root, *ifa;
|
||||
const int afs[] = { AF_INET, AF_INET6, OS_AF_NULL };
|
||||
|
||||
err = os_getifaddrs(&ifa_root, afs);
|
||||
CU_ASSERT_EQUAL_FATAL(err, 0);
|
||||
for (ifa = ifa_root; ifa; ifa = ifa->next) {
|
||||
CU_ASSERT_PTR_NOT_EQUAL_FATAL(ifa->addr, NULL);
|
||||
CU_ASSERT(ifa->addr->sa_family == AF_INET ||
|
||||
ifa->addr->sa_family == AF_INET6);
|
||||
if (ifa->addr->sa_family == AF_INET) {
|
||||
have_ipv4 = 1;
|
||||
} else if (ifa->addr->sa_family == AF_INET6) {
|
||||
have_ipv6 = 1;
|
||||
}
|
||||
}
|
||||
|
||||
CU_ASSERT_EQUAL(have_ipv4, 1);
|
||||
CU_ASSERT_EQUAL(have_ipv6, 1);
|
||||
|
||||
os_freeifaddrs(ifa_root);
|
||||
|
||||
CU_PASS("IPv6 enabled in test environment");
|
||||
} else {
|
||||
CU_PASS("IPv6 disabled in test environment");
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* OS_SOCKET_HAS_IPV6 */
|
0
src/os/tests/iter.c
Executable file → Normal file
0
src/os/tests/iter.c
Executable file → Normal file
0
src/os/tests/stdlib.c
Executable file → Normal file
0
src/os/tests/stdlib.c
Executable file → Normal file
Loading…
Add table
Add a link
Reference in a new issue