summaryrefslogtreecommitdiff
path: root/agent/address.c
diff options
context:
space:
mode:
authorYouness Alaoui <kakaroto@kakaroto.(none)>2008-10-30 17:24:17 -0400
committerYouness Alaoui <kakaroto@kakaroto.(none)>2008-10-30 17:24:17 -0400
commit4efdfdcee86d9ebf42a797623a34c90053c45c39 (patch)
tree8192f76ae94f0dbec8d2c482369e02ad05baf429 /agent/address.c
parentde6e8a7efd39e340916f74b8e0f6d28921288c52 (diff)
downloadlibnice-4efdfdcee86d9ebf42a797623a34c90053c45c39.tar.gz
Move address into the agent's dir
Diffstat (limited to 'agent/address.c')
-rw-r--r--agent/address.c343
1 files changed, 343 insertions, 0 deletions
diff --git a/agent/address.c b/agent/address.c
new file mode 100644
index 0000000..01810e3
--- /dev/null
+++ b/agent/address.c
@@ -0,0 +1,343 @@
+/*
+ * This file is part of the Nice GLib ICE library.
+ *
+ * (C) 2006, 2007 Collabora Ltd.
+ * Contact: Dafydd Harries
+ * (C) 2006, 2007 Nokia Corporation. All rights reserved.
+ * Contact: Kai Vehmanen
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Nice GLib ICE library.
+ *
+ * The Initial Developers of the Original Code are Collabora Ltd and Nokia
+ * Corporation. All Rights Reserved.
+ *
+ * Contributors:
+ * Dafydd Harries, Collabora Ltd.
+ * Kai Vehmanen, Nokia
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * the GNU Lesser General Public License Version 2.1 (the "LGPL"), in which
+ * case the provisions of LGPL are applicable instead of those above. If you
+ * wish to allow use of your version of this file only under the terms of the
+ * LGPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replace
+ * them with the notice and other provisions required by the LGPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the LGPL.
+ */
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <string.h>
+
+#include "address.h"
+
+
+NICEAPI_EXPORT NiceAddress *
+nice_address_new (void)
+{
+ NiceAddress *addr = g_slice_new0 (NiceAddress);
+ nice_address_init (addr);
+ return addr;
+}
+
+
+NICEAPI_EXPORT void
+nice_address_set_ipv4 (NiceAddress *addr, guint32 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;
+ addr->s.ip4.sin_port = 0;
+}
+
+
+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);
+ addr->s.ip6.sin6_port = addr->s.ip6.sin6_scope_id = 0;
+}
+
+
+NICEAPI_EXPORT void
+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)
+{
+ 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_from_string ()
+ *
+ * Returns FALSE on error.
+ */
+NICEAPI_EXPORT gboolean
+nice_address_set_from_string (NiceAddress *addr, const gchar *str)
+{
+#ifdef G_OS_WIN32
+ union {
+ struct sockaddr addr;
+ struct sockaddr_in ip4;
+ struct sockaddr_in6 ip6;
+ } s;
+ int len4 = sizeof(s.ip4);
+ int len6 = sizeof(s.ip6);
+ if (WSAStringToAddress((char *)str, AF_INET, NULL, &s.addr, &len4) == 0)
+ nice_address_set_from_sockaddr (addr, &s.addr);
+ else if (WSAStringToAddress((char *)str, AF_INET6, NULL, &s.addr, &len6) == 0)
+ nice_address_set_from_sockaddr (addr, &s.addr);
+ else
+ return FALSE; /* Invalid address */
+#else
+ 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 if (inet_pton (AF_INET6, str, &a.ipv6) > 0)
+ nice_address_set_ipv6 (addr, a.ipv6.s6_addr);
+ else
+ return FALSE; /* Invalid address */
+#endif
+
+ return TRUE;
+}
+
+
+/**
+ * Sets address to match socket address struct 'sin'.
+ */
+NICEAPI_EXPORT void
+nice_address_set_from_sockaddr (NiceAddress *addr,
+ const struct sockaddr *sa)
+{
+ switch (sa->sa_family)
+ {
+ 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();
+ }
+}
+
+
+/**
+ * Copies NiceAddress to socket address struct 'sin'.
+ */
+NICEAPI_EXPORT void
+nice_address_copy_to_sockaddr (const NiceAddress *addr,
+ struct sockaddr *sa)
+{
+ struct sockaddr_in *sin4 = (struct sockaddr_in *)sa;
+ struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sa;
+
+ g_assert (sa);
+
+ switch (addr->s.addr.sa_family)
+ {
+ 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 ();
+ }
+}
+
+NICEAPI_EXPORT void
+nice_address_to_string (const NiceAddress *addr, gchar *dst)
+{
+#ifdef G_OS_WIN32
+ DWORD len;
+ int ret;
+
+ switch (addr->s.addr.sa_family) {
+ case AF_INET:
+ len = INET_ADDRSTRLEN;
+ ret = WSAAddressToString ((LPSOCKADDR)&addr->s.ip4, sizeof(addr->s.ip6),
+ NULL, dst, &len);
+ break;
+ case AF_INET6:
+ len = INET6_ADDRSTRLEN;
+ ret = WSAAddressToString ((LPSOCKADDR)&addr->s.ip6, sizeof(addr->s.ip6),
+ NULL, dst, &len);
+ break;
+ default:
+ g_assert_not_reached();
+ }
+
+#else
+ const gchar *ret = NULL;
+
+ switch (addr->s.addr.sa_family) {
+ case AF_INET:
+ ret = inet_ntop (AF_INET, &addr->s.ip4.sin_addr, dst, INET_ADDRSTRLEN);
+ break;
+ case AF_INET6:
+ ret = inet_ntop (AF_INET6, &addr->s.ip6.sin6_addr, dst,
+ INET6_ADDRSTRLEN);
+ break;
+ default:
+ g_assert_not_reached();
+ }
+#endif
+}
+
+
+NICEAPI_EXPORT gboolean
+nice_address_equal (const NiceAddress *a, const NiceAddress *b)
+{
+ if (a->s.addr.sa_family != b->s.addr.sa_family)
+ return FALSE;
+
+ 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);
+ }
+
+ g_assert_not_reached ();
+}
+
+
+NICEAPI_EXPORT NiceAddress *
+nice_address_dup (const NiceAddress *a)
+{
+ NiceAddress *dup = g_slice_new0 (NiceAddress);
+
+ *dup = *a;
+ return dup;
+}
+
+
+NICEAPI_EXPORT void
+nice_address_free (NiceAddress *addr)
+{
+ g_slice_free (NiceAddress, addr);
+}
+
+
+/* "private" in the sense of "not routable on the Internet" */
+static gboolean
+ipv4_address_is_private (guint32 addr)
+{
+ addr = ntohl (addr);
+
+ /* http://tools.ietf.org/html/rfc3330 */
+ return (
+ /* 10.0.0.0/8 */
+ ((addr & 0xff000000) == 0x0a000000) ||
+ /* 172.16.0.0/12 */
+ ((addr & 0xfff00000) == 0xac100000) ||
+ /* 192.168.0.0/16 */
+ ((addr & 0xffff0000) == 0xc0a80000) ||
+ /* 127.0.0.0/8 */
+ ((addr & 0xff000000) == 0x7f000000));
+}
+
+
+static gboolean
+ipv6_address_is_private (const guchar *addr)
+{
+ return (
+ /* fe80::/10 */
+ ((addr[0] == 0xfe) && ((addr[1] & 0xc) == 0x80)) ||
+ /* fc00::/7 */
+ ((addr[0] & 0xfe) == 0xfc) ||
+ /* ::1 loopback */
+ ((memcmp (addr, "\x00\x00\x00\x00"
+ "\x00\x00\x00\x00"
+ "\x00\x00\x00\x00"
+ "\x00\x00\x00\x01", 16) == 0)));
+}
+
+
+NICEAPI_EXPORT gboolean
+nice_address_is_private (const NiceAddress *a)
+{
+ 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);
+ }
+
+ g_assert_not_reached ();
+}
+
+
+NICEAPI_EXPORT gboolean
+nice_address_is_valid (const NiceAddress *a)
+{
+ switch (a->s.addr.sa_family)
+ {
+ case AF_INET:
+ case AF_INET6:
+ return TRUE;
+ default:
+ return FALSE;
+ }
+}