#include <assert.h>
#include "dds/ddsrt/cdtors.h"
#include "dds/ddsrt/ifaddrs.h"
#include "dds/ddsrt/retcode.h"
#include "CUnit/Test.h"
#ifdef DDSRT_HAVE_IPV6
static int ipv6_enabled = 1;
#endif
CU_Init(ddsrt_getifaddrs)
{
ddsrt_init();
#ifdef DDSRT_HAVE_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
#endif
return 0;
}
CU_Clean(ddsrt_getifaddrs)
{
ddsrt_fini();
return 0;
}
CU_Test(ddsrt_getifaddrs, ipv4)
{
dds_return_t ret;
int seen = 0;
ddsrt_ifaddrs_t *ifa_root, *ifa;
const int afs[] = { AF_INET, DDSRT_AF_TERM };
ret = ddsrt_getifaddrs(&ifa_root, afs);
CU_ASSERT_EQ_FATAL (ret, DDS_RETCODE_OK);
for (ifa = ifa_root; ifa; ifa = ifa->next) {
CU_ASSERT_NEQ_FATAL (ifa->addr, NULL);
CU_ASSERT_EQ (ifa->addr->sa_family, AF_INET);
if (ifa->addr->sa_family == AF_INET) {
if (ifa->flags & IFF_LOOPBACK) {
CU_ASSERT (ddsrt_sockaddr_isloopback(ifa->addr));
} else {
CU_ASSERT (!ddsrt_sockaddr_isloopback(ifa->addr));
}
seen = 1;
}
}
CU_ASSERT_EQ (seen, 1);
ddsrt_freeifaddrs(ifa_root);
}
CU_Test(ddsrt_getifaddrs, null_filter)
{
dds_return_t ret;
int cnt = 0;
ddsrt_ifaddrs_t *ifa_root, *ifa;
ret = ddsrt_getifaddrs(&ifa_root, NULL);
CU_ASSERT_EQ_FATAL (ret, DDS_RETCODE_OK);
for (ifa = ifa_root; ifa; ifa = ifa->next) {
CU_ASSERT_NEQ_FATAL (ifa->addr, NULL);
cnt++;
}
CU_ASSERT_GT (cnt, 0);
ddsrt_freeifaddrs(ifa_root);
}
CU_Test(ddsrt_getifaddrs, empty_filter)
{
dds_return_t ret;
ddsrt_ifaddrs_t *ifa_root;
const int afs[] = { DDSRT_AF_TERM };
ret = ddsrt_getifaddrs(&ifa_root, afs);
CU_ASSERT_EQ_FATAL (ret, DDS_RETCODE_OK);
CU_ASSERT_EQ (ifa_root, NULL);
ddsrt_freeifaddrs(ifa_root);
}
CU_Test(ddsrt_getifaddrs, ipv6)
{
#ifdef DDSRT_HAVE_IPV6
if (ipv6_enabled == 1) {
dds_return_t ret;
int have_ipv6 = 0;
ddsrt_ifaddrs_t *ifa_root, *ifa;
const int afs[] = { AF_INET6, DDSRT_AF_TERM };
ret = ddsrt_getifaddrs(&ifa_root, afs);
CU_ASSERT_EQ_FATAL (ret, DDS_RETCODE_OK);
for (ifa = ifa_root; ifa; ifa = ifa->next) {
CU_ASSERT_NEQ_FATAL (ifa->addr, NULL);
CU_ASSERT_EQ (ifa->addr->sa_family, AF_INET6);
if (ifa->addr->sa_family == AF_INET6) {
have_ipv6 = 1;
if (ddsrt_sockaddr_isloopback(ifa->addr)) {
CU_ASSERT_NEQ (ifa->flags & IFF_LOOPBACK, 0);
}
}
}
CU_ASSERT_EQ (have_ipv6, 1);
ddsrt_freeifaddrs(ifa_root);
CU_PASS("IPv6 enabled in test environment");
} else {
CU_PASS("IPv6 disabled in test environment");
}
#else
CU_PASS("IPv6 is not supported");
#endif
}
CU_Test(ddsrt_getifaddrs, ipv4_n_ipv6)
{
#if DDSRT_HAVE_IPV6
if (ipv6_enabled == 1) {
dds_return_t ret;
int have_ipv4 = 0;
int have_ipv6 = 0;
ddsrt_ifaddrs_t *ifa_root, *ifa;
const int afs[] = { AF_INET, AF_INET6, DDSRT_AF_TERM };
ret = ddsrt_getifaddrs(&ifa_root, afs);
CU_ASSERT_EQ_FATAL (ret, DDS_RETCODE_OK);
for (ifa = ifa_root; ifa; ifa = ifa->next) {
CU_ASSERT_NEQ_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_EQ (have_ipv4, 1);
CU_ASSERT_EQ (have_ipv6, 1);
ddsrt_freeifaddrs(ifa_root);
CU_PASS("IPv6 enabled in test environment");
} else {
CU_PASS("IPv6 disabled in test environment");
}
#else
CU_PASS("IPv6 is not supported");
#endif
}