Change socket function signatures to use os_sockaddr
* Consolidated and cleaned up some (duplicate) functions. * Removed some unused functions that did not make sense to keep around. Signed-off-by: Jeroen Koekkoek <jeroen@koekkoek.nl>
This commit is contained in:
parent
ea3f5e7ff4
commit
7ba3bca087
20 changed files with 275 additions and 506 deletions
|
@ -110,12 +110,6 @@ extern "C" {
|
|||
|
||||
#define SD_FLAG_IS_SET(flags, flag) ((((uint32_t)(flags) & (uint32_t)(flag))) != 0U)
|
||||
|
||||
typedef struct {
|
||||
uint8_t af_inet : 1;
|
||||
uint8_t af_inet6 : 1;
|
||||
uint8_t af_packet : 1;
|
||||
} os_ifaddr_filter_t;
|
||||
|
||||
/** Network interface attributes */
|
||||
typedef struct os_ifaddrs_s {
|
||||
struct os_ifaddrs_s *next;
|
||||
|
@ -137,14 +131,17 @@ extern "C" {
|
|||
* 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] ifilt FIXME: comment
|
||||
* @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.
|
||||
*
|
||||
* @returns Returns zero on success or a valid errno value on error.
|
||||
*/
|
||||
OSAPI_EXPORT _Success_(return == 0) int
|
||||
os_getifaddrs(
|
||||
_Inout_ os_ifaddrs_t **ifap,
|
||||
_In_ const os_ifaddr_filter_t *ifilt);
|
||||
_In_opt_ const int *const afs);
|
||||
|
||||
/**
|
||||
* @brief Free os_ifaddrs_t structure list allocated by os_getifaddrs()
|
||||
|
@ -252,20 +249,46 @@ 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 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_sockaddr_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);
|
||||
/**
|
||||
* 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 convert to host order
|
||||
* @pre sa is a valid sockaddr pointer
|
||||
*/
|
||||
OSAPI_EXPORT uint16_t
|
||||
os_sockaddr_get_port(const os_sockaddr *const sa) __nonnull_all__;
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
OSAPI_EXPORT int
|
||||
os_sockaddrIpAddressCompare(const os_sockaddr* addr1,
|
||||
const os_sockaddr* addr2) __nonnull_all__
|
||||
__attribute_pure__;
|
||||
os_sockaddr_compare(
|
||||
const os_sockaddr *sa1,
|
||||
const os_sockaddr *sa2) __nonnull_all__ __attribute_pure__;
|
||||
|
||||
/**
|
||||
* FIXME: comment
|
||||
*/
|
||||
OSAPI_EXPORT int
|
||||
os_sockaddr_is_unspecified(
|
||||
const os_sockaddr *const sa) __nonnull_all__;
|
||||
|
||||
/* docced in implementation file */
|
||||
OSAPI_EXPORT bool
|
||||
|
@ -284,20 +307,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.
|
||||
*
|
||||
|
@ -323,16 +332,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
|
||||
|
@ -342,26 +341,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);
|
||||
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
|
|
@ -263,7 +263,7 @@ extern "C" {
|
|||
__attribute_warn_unused_result__;
|
||||
|
||||
void *
|
||||
os_memdup(void *src, size_t n);
|
||||
os_memdup(const void *src, size_t n);
|
||||
|
||||
/** \brief os_strsep wrapper
|
||||
*
|
||||
|
|
|
@ -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,113 @@ 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)
|
||||
size_t
|
||||
os_sockaddr_size(const os_sockaddr *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 == 1)
|
||||
static
|
||||
void os__sockaddrInit6(os_sockaddr* 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
|
||||
|
||||
|
||||
/**
|
||||
* 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);
|
||||
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 result;
|
||||
return sz;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 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)
|
||||
uint16_t os_sockaddr_get_port(const os_sockaddr *sa)
|
||||
{
|
||||
bool result = false;
|
||||
#if (OS_SOCKET_HAS_IPV6 == 1)
|
||||
os_sockaddr_in6 * thisV6, * thatV6;
|
||||
#endif
|
||||
unsigned short port = 0;
|
||||
|
||||
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 (OS_SOCKET_HAS_IPV6 == 1)
|
||||
else
|
||||
{
|
||||
/* 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);
|
||||
}
|
||||
#endif
|
||||
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;
|
||||
}
|
||||
|
||||
int
|
||||
os_sockaddrIpAddressCompare(const os_sockaddr* addr1,
|
||||
const os_sockaddr* addr2)
|
||||
int os_sockaddr_compare(const os_sockaddr *sa1, const os_sockaddr *sa2)
|
||||
{
|
||||
int result = -1;
|
||||
uint16_t port1, port2;
|
||||
int r;
|
||||
int eq;
|
||||
size_t sz;
|
||||
|
||||
assert(sa1 != 0);
|
||||
assert(sa2 != 0);
|
||||
|
||||
if ((eq = sa1->sa_family - sa2->sa_family) == 0) {
|
||||
switch(sa1->sa_family) {
|
||||
#if (OS_SOCKET_HAS_IPV6 == 1)
|
||||
os_sockaddr_in6 * thisV6, * thatV6;
|
||||
#endif
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (((os_sockaddr_in*)addr1)->sin_addr.s_addr >
|
||||
((os_sockaddr_in*)addr2)->sin_addr.s_addr) {
|
||||
result = 1;
|
||||
} else {
|
||||
result = -1;
|
||||
}
|
||||
case AF_INET6:
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
#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;
|
||||
}
|
||||
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);
|
||||
}
|
||||
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;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
return result;
|
||||
|
||||
return eq;
|
||||
}
|
||||
|
||||
int os_sockaddr_is_unspecified(const os_sockaddr *const sa)
|
||||
{
|
||||
int unspec = 0;
|
||||
|
||||
assert(sa != NULL);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
return unspec;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -342,7 +280,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 +292,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 +312,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 +336,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;
|
||||
}
|
||||
|
|
|
@ -12,57 +12,37 @@
|
|||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
#if defined(__linux)
|
||||
#include <linux/if_packet.h> /* sockaddr_ll */
|
||||
#endif /* __linux */
|
||||
|
||||
#include "os/os.h"
|
||||
|
||||
static int
|
||||
copy_ifaddrs(os_ifaddrs_t **ifap, const struct ifaddrs *sys_ifa)
|
||||
copyaddr(os_ifaddrs_t **ifap, const struct ifaddrs *sys_ifa)
|
||||
{
|
||||
int err = 0;
|
||||
os_ifaddrs_t *ifa;
|
||||
size_t size;
|
||||
ssize_t sz;
|
||||
|
||||
assert(ifap != NULL);
|
||||
assert(sys_ifa != NULL);
|
||||
assert(sys_ifa->ifa_addr->sa_family == AF_INET
|
||||
#ifdef __linux
|
||||
|| sys_ifa->ifa_addr->sa_family == AF_PACKET
|
||||
#endif /* __linux */
|
||||
|| sys_ifa->ifa_addr->sa_family == AF_INET6);
|
||||
|
||||
ifa = os_malloc(sizeof(*ifa));
|
||||
sz = os_sockaddr_size(sys_ifa->ifa_addr);
|
||||
ifa = os_calloc_s(1, sizeof(*ifa));
|
||||
if (ifa == NULL) {
|
||||
err = errno;
|
||||
} else {
|
||||
(void)memset(ifa, 0, sizeof(*ifa));
|
||||
|
||||
ifa->index = if_nametoindex(sys_ifa->ifa_name);
|
||||
ifa->flags = sys_ifa->ifa_flags;
|
||||
if ((ifa->name = os_strdup(sys_ifa->ifa_name)) == NULL) {
|
||||
err = errno;
|
||||
} else if (sys_ifa->ifa_addr->sa_family == AF_INET6) {
|
||||
size = sizeof(struct sockaddr_in6);
|
||||
if (!(ifa->addr = os_memdup(sys_ifa->ifa_addr, size))) {
|
||||
err = errno;
|
||||
}
|
||||
} else {
|
||||
if (sys_ifa->ifa_addr->sa_family == AF_INET) {
|
||||
size = sizeof(struct sockaddr_in);
|
||||
#ifdef __linux
|
||||
} else {
|
||||
assert(sys_ifa->ifa_addr->sa_family == AF_PACKET);
|
||||
size = sizeof(struct sockaddr_ll);
|
||||
#endif /* __linux */
|
||||
if (!(ifa->addr = os_memdup(sys_ifa->ifa_addr, sz))) {
|
||||
err = errno;
|
||||
}
|
||||
|
||||
if (!(ifa->addr = os_memdup(sys_ifa->ifa_addr, size)) ||
|
||||
(sys_ifa->ifa_netmask &&
|
||||
!(ifa->netmask = os_memdup(sys_ifa->ifa_netmask, size))) ||
|
||||
(sys_ifa->ifa_broadaddr &&
|
||||
!(ifa->broadaddr = os_memdup(sys_ifa->ifa_broadaddr, size))))
|
||||
} else {
|
||||
assert(sys_ifa->ifa_netmask != NULL);
|
||||
if (!(ifa->addr = os_memdup(sys_ifa->ifa_addr, sz)) ||
|
||||
!(ifa->netmask = os_memdup(sys_ifa->ifa_netmask, sz)) ||
|
||||
((sys_ifa->ifa_flags & IFF_BROADCAST) &&
|
||||
!(ifa->broadaddr = os_memdup(sys_ifa->ifa_broadaddr, sz))))
|
||||
{
|
||||
err = errno;
|
||||
}
|
||||
|
@ -81,15 +61,15 @@ copy_ifaddrs(os_ifaddrs_t **ifap, const struct ifaddrs *sys_ifa)
|
|||
_Success_(return == 0) int
|
||||
os_getifaddrs(
|
||||
_Inout_ os_ifaddrs_t **ifap,
|
||||
_In_opt_ const os_ifaddr_filter_t *ifltr)
|
||||
_In_opt_ const int *const afs)
|
||||
{
|
||||
int err = 0;
|
||||
int use;
|
||||
os_ifaddrs_t *ifa, *ifa_root, *ifa_next;
|
||||
struct ifaddrs *sys_ifa, *sys_ifa_root;
|
||||
struct sockaddr *addr;
|
||||
struct sockaddr *sa;
|
||||
|
||||
assert(ifap != NULL);
|
||||
assert(ifltr != NULL);
|
||||
|
||||
if (getifaddrs(&sys_ifa_root) == -1) {
|
||||
err = errno;
|
||||
|
@ -97,19 +77,17 @@ os_getifaddrs(
|
|||
ifa = ifa_root = NULL;
|
||||
|
||||
for (sys_ifa = sys_ifa_root;
|
||||
sys_ifa != NULL && err == 0;
|
||||
sys_ifa != NULL && sys_ifa->ifa_addr != NULL && err == 0;
|
||||
sys_ifa = sys_ifa->ifa_next)
|
||||
{
|
||||
addr = sys_ifa->ifa_addr;
|
||||
if ((addr->sa_family == AF_INET && ifltr->af_inet)
|
||||
#ifdef __linux
|
||||
|| (addr->sa_family == AF_PACKET && ifltr->af_packet)
|
||||
#endif /* __linux */
|
||||
|| (addr->sa_family == AF_INET6 && ifltr->af_inet6 &&
|
||||
!IN6_IS_ADDR_UNSPECIFIED(
|
||||
&((struct sockaddr_in6 *)addr)->sin6_addr)))
|
||||
{
|
||||
err = copy_ifaddrs(&ifa_next, sys_ifa);
|
||||
sa = sys_ifa->ifa_addr;
|
||||
use = (afs == NULL);
|
||||
for (int i = 0; !use && afs[i] != 0; 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;
|
||||
|
|
|
@ -12,11 +12,11 @@
|
|||
#include "os/os.h"
|
||||
|
||||
void *
|
||||
os_memdup(void *src, size_t n)
|
||||
os_memdup(const void *src, size_t n)
|
||||
{
|
||||
void *dest;
|
||||
void *dest = NULL;
|
||||
|
||||
if ((dest = os_malloc_s(n)) != NULL) {
|
||||
if (n != 0 && (dest = os_malloc_s(n)) != NULL) {
|
||||
memcpy(dest, src, n);
|
||||
}
|
||||
|
||||
|
|
|
@ -15,14 +15,9 @@ _Ret_z_
|
|||
_Check_return_
|
||||
char *
|
||||
os_strdup(
|
||||
_In_z_ const char *s1)
|
||||
_In_z_ const char *str)
|
||||
{
|
||||
size_t len;
|
||||
char *dup;
|
||||
assert(str != NULL);
|
||||
|
||||
len = strlen(s1) + 1;
|
||||
dup = os_malloc(len);
|
||||
memcpy(dup, s1, len);
|
||||
|
||||
return dup;
|
||||
return os_memdup(str, strlen(str) + 1);
|
||||
}
|
||||
|
|
|
@ -23,7 +23,7 @@ getifaces(PIP_ADAPTER_ADDRESSES *ptr)
|
|||
ULONG ret;
|
||||
size_t i;
|
||||
|
||||
static const size_t max = 3;
|
||||
static const size_t max = 2;
|
||||
static const ULONG filter = GAA_FLAG_INCLUDE_PREFIX |
|
||||
GAA_FLAG_SKIP_ANYCAST |
|
||||
GAA_FLAG_SKIP_MULTICAST |
|
||||
|
@ -207,9 +207,10 @@ copyaddr(
|
|||
_Success_(return == 0) int
|
||||
os_getifaddrs(
|
||||
_Inout_ os_ifaddrs_t **ifap,
|
||||
_In_opt_ const os_ifaddr_filter_t *ifltr)
|
||||
_In_opt_ const int *const afs)
|
||||
{
|
||||
int err = 0;
|
||||
int use;
|
||||
PIP_ADAPTER_ADDRESSES ifaces = NULL, iface;
|
||||
PIP_ADAPTER_UNICAST_ADDRESS addr = NULL;
|
||||
PMIB_IPADDRTABLE addrtable = NULL;
|
||||
|
@ -217,7 +218,6 @@ os_getifaddrs(
|
|||
struct sockaddr *sa;
|
||||
|
||||
assert(ifap != NULL);
|
||||
assert(ifltr != NULL);
|
||||
|
||||
ifa = ifa_root = ifa_next = NULL;
|
||||
|
||||
|
@ -230,9 +230,12 @@ os_getifaddrs(
|
|||
addr = addr->Next)
|
||||
{
|
||||
sa = (struct sockaddr *)addr->Address.lpSockaddr;
|
||||
if ((sa->sa_family == AF_INET && ifltr->af_inet) ||
|
||||
(sa->sa_family == AF_INET6 && ifltr->af_inet6))
|
||||
{
|
||||
use = (afs == NULL);
|
||||
for (int i = 0; !use && afs[i] != 0; i++) {
|
||||
use = (afs[i] == sa->sa_family);
|
||||
}
|
||||
|
||||
if (use) {
|
||||
err = copyaddr(&ifa_next, iface, addrtable, addr);
|
||||
if (err == 0) {
|
||||
if (ifa == NULL) {
|
||||
|
|
|
@ -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) (
|
||||
|
|
|
@ -36,9 +36,9 @@ CUnit_Test(os_getifaddrs, ipv4)
|
|||
int err;
|
||||
int seen = 0;
|
||||
os_ifaddrs_t *ifa_root, *ifa;
|
||||
os_ifaddr_filter_t ifltr = { .af_inet = 1 };
|
||||
const int afs[] = { AF_INET, 0 };
|
||||
|
||||
err = os_getifaddrs(&ifa_root, &ifltr);
|
||||
err = os_getifaddrs(&ifa_root, afs);
|
||||
CU_ASSERT_EQUAL_FATAL(err, 0);
|
||||
for (ifa = ifa_root; ifa; ifa = ifa->next) {
|
||||
CU_ASSERT_EQUAL(ifa->addr->sa_family, AF_INET);
|
||||
|
@ -62,9 +62,9 @@ CUnit_Test(os_getifaddrs, non_local_ipv6)
|
|||
{
|
||||
int err;
|
||||
os_ifaddrs_t *ifa_root, *ifa;
|
||||
os_ifaddr_filter_t ifltr = { .af_inet6 = 1 };
|
||||
const int afs[] = { AF_INET6, 0 };
|
||||
|
||||
err = os_getifaddrs(&ifa_root, &ifltr);
|
||||
err = os_getifaddrs(&ifa_root, afs);
|
||||
CU_ASSERT_EQUAL_FATAL(err, 0);
|
||||
for (ifa = ifa_root; ifa; ifa = ifa->next) {
|
||||
CU_ASSERT_EQUAL(ifa->addr->sa_family, AF_INET6);
|
||||
|
|
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