summaryrefslogtreecommitdiff
path: root/address
diff options
context:
space:
mode:
authorKai Vehmanen <first.surname@nokia.com>2007-08-29 13:13:00 +0000
committerKai Vehmanen <first.surname@nokia.com>2007-08-29 13:13:00 +0000
commit8f3a86f92e3782e69c6068109e1ada2cb62d8aae (patch)
tree8ab250f2f9cbfcece56a7bfb456b4ed615722209 /address
parentd88379ee53aaa271d4d3014c0d8dea01bf4d0745 (diff)
downloadlibnice-8f3a86f92e3782e69c6068109e1ada2cb62d8aae.tar.gz
Modified address module API to use standard berkeley socket API defines and data structs.
darcs-hash:20070829131320-77cd4-03f2b1b4246f8fac33d5f1573ef77cf23a2465d6.gz
Diffstat (limited to 'address')
-rw-r--r--address/address.c205
-rw-r--r--address/address.h33
-rw-r--r--address/test.c26
3 files changed, 160 insertions, 104 deletions
diff --git a/address/address.c b/address/address.c
index 19d380a..e691396 100644
--- a/address/address.c
+++ b/address/address.c
@@ -51,72 +51,118 @@
NICEAPI_EXPORT NiceAddress *
nice_address_new (void)
{
- return g_slice_new0 (NiceAddress);
+ NiceAddress *addr = g_slice_new0 (NiceAddress);
+ memset (addr, 0, sizeof (addr));
+ addr->s.addr.sa_family = AF_UNSPEC;
+#ifdef HAVE_SA_LEN
+ addr->s.addr.sa_len = sizeof (addr->s.addr);
+#endif
+ return addr;
}
NICEAPI_EXPORT void
nice_address_set_ipv4 (NiceAddress *addr, guint32 addr_ipv4)
{
- addr->type = NICE_ADDRESS_TYPE_IPV4;
- addr->addr.addr_ipv4 = addr_ipv4;
+ addr->s.ip4.sin_family = AF_INET;
+#ifdef HAVE_SA_LEN
+ addr->s.ip4.sin_len = sizeof (addr->sa.ip4);
+#endif
+ addr->s.ip4.sin_addr.s_addr = addr_ipv4 ? htonl (addr_ipv4) : INADDR_ANY;
+}
+
+
+NICEAPI_EXPORT void
+nice_address_set_ipv6 (NiceAddress *addr, const guchar *addr_ipv6)
+{
+ addr->s.ip6.sin6_family = AF_INET6;
+#ifdef HAVE_SA_LEN
+ addr->s.ip6.sin6_len = sizeof (addr->sa.ip6);
+#endif
+ memcpy (addr->s.ip6.sin6_addr.s6_addr, addr_ipv6, 16);
}
NICEAPI_EXPORT void
-nice_address_set_ipv6 (NiceAddress *addr, const gchar *addr_ipv6)
+nice_address_set_port (NiceAddress *addr, guint port)
+{
+ g_assert (addr);
+
+ switch (addr->s.addr.sa_family)
+ {
+ case AF_INET:
+ addr->s.ip4.sin_port = htons (port);
+ break;
+ case AF_INET6:
+ addr->s.ip6.sin6_port = htons (port);
+ break;
+ default:
+ g_assert_not_reached();
+ }
+}
+
+
+guint
+nice_address_get_port (const NiceAddress *addr)
{
- addr->type = NICE_ADDRESS_TYPE_IPV6;
- memcpy (addr->addr.addr_ipv6, addr_ipv6, sizeof (addr->addr.addr_ipv6));
+ g_assert (addr);
+
+ switch (addr->s.addr.sa_family)
+ {
+ case AF_INET:
+ return ntohs (addr->s.ip4.sin_port);
+ case AF_INET6:
+ return ntohs (addr->s.ip6.sin6_port);
+ }
+
+ g_assert_not_reached();
}
/**
- * address_set_ipv4_from_string ()
+ * address_set_from_string ()
*
* Returns FALSE on error.
*/
NICEAPI_EXPORT gboolean
-nice_address_set_ipv4_from_string (NiceAddress *addr, const gchar *str)
+nice_address_set_from_string (NiceAddress *addr, const gchar *str)
{
- struct in_addr iaddr;
-
- if (inet_aton (str, &iaddr) != 0)
- {
- nice_address_set_ipv4 (addr, ntohl (iaddr.s_addr));
- return TRUE;
- }
+ union
+ {
+ struct in_addr ipv4;
+ struct in6_addr ipv6;
+ } a;
+
+ if (inet_pton (AF_INET, str, &a.ipv4) > 0)
+ nice_address_set_ipv4 (addr, ntohl (a.ipv4.s_addr));
else
- {
- /* invalid address */
- return FALSE;
- }
+ if (inet_pton (AF_INET6, str, &a.ipv6) > 0)
+ nice_address_set_ipv6 (addr, a.ipv6.s6_addr);
+ else
+ return FALSE; /* Invalid address */
+
+ return TRUE;
}
+
/**
* Sets address to match socket address struct 'sin'.
*/
NICEAPI_EXPORT void
-nice_address_set_from_sockaddr (NiceAddress *addr, const struct sockaddr *sin)
+nice_address_set_from_sockaddr (NiceAddress *addr,
+ const struct sockaddr *sa)
{
- const struct sockaddr_in *sin4 = (const struct sockaddr_in *)sin;
- const struct sockaddr_in6 *sin6 = (const struct sockaddr_in6 *)sin;
-
- g_assert (sin4->sin_family == AF_INET || sin4->sin_family == AF_INET6);
-
- if (sin4->sin_family == AF_INET)
- {
- addr->type = NICE_ADDRESS_TYPE_IPV4;
- nice_address_set_ipv4 (addr, ntohl (sin4->sin_addr.s_addr));
- }
- else /* (sin4->sin_family == AF_INET6) */
+ switch (sa->sa_family)
{
- addr->type = NICE_ADDRESS_TYPE_IPV6;
- nice_address_set_ipv6 (addr,
- (gchar *) &sin6->sin6_addr);
+ case AF_INET:
+ memcpy(&addr->s.ip4, sa, sizeof (addr->s.ip4));
+ break;
+ case AF_INET6:
+ memcpy(&addr->s.ip6, sa, sizeof (addr->s.ip6));
+ break;
+ default:
+ g_assert_not_reached();
}
-
- addr->port = ntohs (sin4->sin_port);
}
@@ -124,45 +170,43 @@ nice_address_set_from_sockaddr (NiceAddress *addr, const struct sockaddr *sin)
* Copies NiceAddress to socket address struct 'sin'.
*/
NICEAPI_EXPORT void
-nice_address_copy_to_sockaddr (const NiceAddress *addr, struct sockaddr *sin)
+nice_address_copy_to_sockaddr (const NiceAddress *addr,
+ struct sockaddr *sa)
{
- struct sockaddr_in *sin4 = (struct sockaddr_in *)sin;
- struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sin;
+ struct sockaddr_in *sin4 = (struct sockaddr_in *)sa;
+ struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sa;
- g_assert (sin);
- g_assert (addr->type == NICE_ADDRESS_TYPE_IPV4 || addr->type == NICE_ADDRESS_TYPE_IPV6);
-
- if (addr->type == NICE_ADDRESS_TYPE_IPV4)
- {
- sin4->sin_family = AF_INET;
- sin4->sin_addr.s_addr = htonl (addr->addr.addr_ipv4);
- }
- else /* (addr->type == NICE_ADDRESS_TYPE_IPV6) */
+ g_assert (sa);
+
+ switch (addr->s.addr.sa_family)
{
- sin4->sin_family = AF_INET6;
- memcpy (&sin6->sin6_addr.s6_addr, addr->addr.addr_ipv6,
- sizeof (addr->addr.addr_ipv6));
+ case AF_INET:
+ memcpy (sin4, &addr->s.ip4, sizeof (*sin4));
+ break;
+ case AF_INET6:
+ memcpy (sin6, &addr->s.ip6, sizeof (*sin6));
+ break;
+ default:
+ g_assert_not_reached ();
}
-
- sin4->sin_port = htons (addr->port);
}
NICEAPI_EXPORT void
-nice_address_to_string (NiceAddress *addr, gchar *dst)
+nice_address_to_string (const NiceAddress *addr, gchar *dst)
{
- struct in_addr iaddr = {0,};
const gchar *ret = NULL;
- switch (addr->type)
+ switch (addr->s.addr.sa_family)
{
- case NICE_ADDRESS_TYPE_IPV4:
- iaddr.s_addr = htonl (addr->addr.addr_ipv4);
- ret = inet_ntop (AF_INET, &iaddr, dst, INET_ADDRSTRLEN);
+ case AF_INET:
+ ret = inet_ntop (AF_INET, &addr->s.ip4.sin_addr, dst, INET_ADDRSTRLEN);
break;
- case NICE_ADDRESS_TYPE_IPV6:
- ret = inet_ntop (AF_INET6, &addr->addr.addr_ipv6, dst,
+ case AF_INET6:
+ ret = inet_ntop (AF_INET6, &addr->s.ip6.sin6_addr, dst,
INET6_ADDRSTRLEN);
break;
+ default:
+ g_assert_not_reached();
}
g_assert (ret == dst);
@@ -172,21 +216,27 @@ nice_address_to_string (NiceAddress *addr, gchar *dst)
NICEAPI_EXPORT gboolean
nice_address_equal (const NiceAddress *a, const NiceAddress *b)
{
- g_assert (a->type == NICE_ADDRESS_TYPE_IPV4 || a->type == NICE_ADDRESS_TYPE_IPV6);
-
- if (a->type != b->type)
+ if (a->s.addr.sa_family != b->s.addr.sa_family)
return FALSE;
- if (a->type == NICE_ADDRESS_TYPE_IPV4)
- return (a->addr.addr_ipv4 == b->addr.addr_ipv4) && (a->port == b->port);
+ switch (a->s.addr.sa_family)
+ {
+ case AF_INET:
+ return (a->s.ip4.sin_addr.s_addr == b->s.ip4.sin_addr.s_addr)
+ && (a->s.ip4.sin_port == b->s.ip4.sin_port);
+
+ case AF_INET6:
+ return IN6_ARE_ADDR_EQUAL (&a->s.ip6.sin6_addr, &b->s.ip6.sin6_addr)
+ && (a->s.ip6.sin6_port == b->s.ip6.sin6_port)
+ && (a->s.ip6.sin6_scope_id == b->s.ip6.sin6_scope_id);
+ }
- else /* (a->type == NICE_ADDRESS_TYPE_IPV6) */
- return (memcmp (a->addr.addr_ipv6, b->addr.addr_ipv6, sizeof (a->addr.addr_ipv6)) == 0) && (a->port == b->port);
+ g_assert_not_reached ();
}
NICEAPI_EXPORT NiceAddress *
-nice_address_dup (NiceAddress *a)
+nice_address_dup (const NiceAddress *a)
{
NiceAddress *dup = g_slice_new0 (NiceAddress);
@@ -206,6 +256,8 @@ nice_address_free (NiceAddress *addr)
static gboolean
ipv4_address_is_private (guint32 addr)
{
+ addr = ntohl (addr);
+
/* http://tools.ietf.org/html/rfc3330 */
return (
/* 10.0.0.0/8 */
@@ -236,13 +288,16 @@ ipv6_address_is_private (const guchar *addr)
NICEAPI_EXPORT gboolean
-nice_address_is_private (NiceAddress *a)
+nice_address_is_private (const NiceAddress *a)
{
- g_assert (a->type == NICE_ADDRESS_TYPE_IPV4 || a->type == NICE_ADDRESS_TYPE_IPV6);
+ switch (a->s.addr.sa_family)
+ {
+ case AF_INET:
+ return ipv4_address_is_private (a->s.ip4.sin_addr.s_addr);
+ case AF_INET6:
+ return ipv6_address_is_private (a->s.ip6.sin6_addr.s6_addr);
+ }
- if (a->type == NICE_ADDRESS_TYPE_IPV4)
- return ipv4_address_is_private (a->addr.addr_ipv4);
- else /* (a->type == NICE_ADDRESS_TYPE_IPV6) */
- return ipv6_address_is_private (a->addr.addr_ipv6);
+ g_assert_not_reached ();
}
diff --git a/address/address.h b/address/address.h
index 79ea1ff..f7444cb 100644
--- a/address/address.h
+++ b/address/address.h
@@ -38,18 +38,14 @@
#ifndef _ADDRESS_H
#define _ADDRESS_H
+#include <sys/types.h>
+#include <sys/socket.h>
#include <netinet/in.h>
#include <glib.h>
G_BEGIN_DECLS
-typedef enum
-{
- NICE_ADDRESS_TYPE_IPV4,
- NICE_ADDRESS_TYPE_IPV6,
-} NiceAddressType;
-
#define NICE_ADDRESS_STRING_LEN INET6_ADDRSTRLEN
typedef struct _NiceAddress NiceAddress;
@@ -57,13 +53,12 @@ typedef struct _NiceAddress NiceAddress;
/* note: clients need to know the storage size, so needs to be public */
struct _NiceAddress
{
- NiceAddressType type;
union
{
- guint32 addr_ipv4;
- guchar addr_ipv6[INET_ADDRSTRLEN];
- } addr;
- guint16 port;
+ struct sockaddr addr;
+ struct sockaddr_in ip4;
+ struct sockaddr_in6 ip6;
+ } s;
};
NiceAddress *
@@ -73,17 +68,23 @@ void
nice_address_free (NiceAddress *addr);
NiceAddress *
-nice_address_dup (NiceAddress *a);
+nice_address_dup (const NiceAddress *a);
void
nice_address_set_ipv4 (NiceAddress *addr, guint32 addr_ipv4);
void
-nice_address_set_ipv6 (NiceAddress *addr, const gchar *addr_ipv6);
+nice_address_set_ipv6 (NiceAddress *addr, const guchar *addr_ipv6);
+
+void
+nice_address_set_port (NiceAddress *addr, guint port);
+
+guint
+nice_address_get_port (const NiceAddress *addr);
G_GNUC_WARN_UNUSED_RESULT
gboolean
-nice_address_set_ipv4_from_string (NiceAddress *addr, const gchar *str);
+nice_address_set_from_string (NiceAddress *addr, const gchar *str);
void
nice_address_set_from_sockaddr (NiceAddress *addr, const struct sockaddr *sin);
@@ -95,10 +96,10 @@ gboolean
nice_address_equal (const NiceAddress *a, const NiceAddress *b);
void
-nice_address_to_string (NiceAddress *addr, gchar *dst);
+nice_address_to_string (const NiceAddress *addr, gchar *dst);
gboolean
-nice_address_is_private (NiceAddress *a);
+nice_address_is_private (const NiceAddress *a);
G_END_DECLS
diff --git a/address/test.c b/address/test.c
index 4e692fd..d770107 100644
--- a/address/test.c
+++ b/address/test.c
@@ -62,7 +62,7 @@ test_ipv4 (void)
memset (&addr, 0, sizeof (addr));
memset (&other, 0, sizeof (other));
nice_address_set_ipv4 (&addr, 0x01020304);
- g_assert (addr.type == NICE_ADDRESS_TYPE_IPV4);
+ g_assert (addr.s.ip4.sin_family == AF_INET);
nice_address_to_string (&addr, str);
g_assert (0 == strcmp (str, "1.2.3.4"));
@@ -74,8 +74,8 @@ test_ipv4 (void)
g_assert (TRUE == nice_address_equal (&addr, &other));
/* from sockaddr_in */
- other.port = 9876; /* in native byte order */
- other.type = NICE_ADDRESS_TYPE_IPV4;
+ nice_address_set_port (&other, 9876); /* in native byte order */
+ other.s.ip4.sin_family = AF_INET;
nice_address_set_from_sockaddr (&addr, (struct sockaddr*)&sin);
nice_address_to_string (&addr, str);
nice_address_to_string (&other, str);
@@ -87,15 +87,15 @@ test_ipv4 (void)
/* different port */
nice_address_set_ipv4 (&other, 0x01020304);
- addr.port = 1;
+ nice_address_set_port (&addr, 1);
g_assert (FALSE == nice_address_equal (&addr, &other));
/* test private address check */
{
NiceAddress *heap_addr = nice_address_new ();
- g_assert (nice_address_set_ipv4_from_string (heap_addr, "127.0.0.1") == TRUE);
+ g_assert (nice_address_set_from_string (heap_addr, "127.0.0.1") == TRUE);
g_assert (nice_address_is_private (heap_addr) == TRUE);
- g_assert (nice_address_set_ipv4_from_string (heap_addr, "127.0.0.1.1") != TRUE);
+ g_assert (nice_address_set_from_string (heap_addr, "127.0.0.1.1") != TRUE);
nice_address_free (heap_addr);
}
}
@@ -107,7 +107,7 @@ test_ipv6 (void)
gchar str[NICE_ADDRESS_STRING_LEN];
struct sockaddr_in6 sin, sin2;
- g_assert (nice_address_set_ipv4_from_string (&v4addr, "172.1.0.1") == TRUE);
+ g_assert (nice_address_set_from_string (&v4addr, "172.1.0.1") == TRUE);
memset (&sin, 0, sizeof (sin));
memset (&sin2, 0, sizeof (sin2));
@@ -117,17 +117,17 @@ test_ipv6 (void)
g_assert (inet_pton (AF_INET6, "11:2233:4455:6677:8899:aabb:ccdd:eeff", &sin.sin6_addr) > 0);
memset (&addr, 0, sizeof (addr));
- nice_address_set_ipv6 (&addr,
+ nice_address_set_ipv6 (&addr, (guchar *)
"\x00\x11\x22\x33"
"\x44\x55\x66\x77"
"\x88\x99\xaa\xbb"
"\xcc\xdd\xee\xff");
- g_assert (addr.type == NICE_ADDRESS_TYPE_IPV6);
+ g_assert (addr.s.ip6.sin6_family == AF_INET6);
nice_address_to_string (&addr, str);
g_assert (0 == strcmp (str, "11:2233:4455:6677:8899:aabb:ccdd:eeff"));
- addr.port = 9876; /* in native byte order */
+ nice_address_set_port (&addr, 9876); /* in native byte order */
nice_address_set_from_sockaddr (&other, (struct sockaddr*)&sin);
nice_address_copy_to_sockaddr (&other, (struct sockaddr*)&sin2);
g_assert (memcmp (&sin, &sin2, sizeof(sin)) == 0);
@@ -136,13 +136,13 @@ test_ipv6 (void)
g_assert (nice_address_equal (&addr, &other) == TRUE);
/* private IPv6 address */
- nice_address_set_ipv6 (&addr,
+ nice_address_set_ipv6 (&addr, (guchar *)
"\xfc\x00\x00\x00"
"\x00\x00\x00\x00"
"\x00\x00\x00\x00"
"\x00\x00\x00\x01");
g_assert (nice_address_is_private (&addr) == TRUE);
- nice_address_set_ipv6 (&addr,
+ nice_address_set_ipv6 (&addr, (guchar *)
"\x00\x00\x00\x00"
"\x00\x00\x00\x00"
"\x00\x00\x00\x00"
@@ -153,7 +153,7 @@ test_ipv6 (void)
g_assert (nice_address_equal (&addr, &v4addr) != TRUE);
/* mismatched type */
- addr.type = -1;
+ addr.s.addr.sa_family = AF_UNSPEC;
/*g_assert (nice_address_equal (&addr, &v4addr) != TRUE);*/
}