diff options
author | Youness Alaoui <kakaroto@kakaroto.(none)> | 2008-10-30 17:24:17 -0400 |
---|---|---|
committer | Youness Alaoui <kakaroto@kakaroto.(none)> | 2008-10-30 17:24:17 -0400 |
commit | 4efdfdcee86d9ebf42a797623a34c90053c45c39 (patch) | |
tree | 8192f76ae94f0dbec8d2c482369e02ad05baf429 /agent/address.c | |
parent | de6e8a7efd39e340916f74b8e0f6d28921288c52 (diff) | |
download | libnice-4efdfdcee86d9ebf42a797623a34c90053c45c39.tar.gz |
Move address into the agent's dir
Diffstat (limited to 'agent/address.c')
-rw-r--r-- | agent/address.c | 343 |
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; + } +} |