2 * This file is part of the Nice GLib ICE library.
4 * (C) 2006-2009 Collabora Ltd.
5 * Contact: Youness Alaoui
6 * (C) 2006-2009 Nokia Corporation. All rights reserved.
7 * Contact: Kai Vehmanen
9 * The contents of this file are subject to the Mozilla Public License Version
10 * 1.1 (the "License"); you may not use this file except in compliance with
11 * the License. You may obtain a copy of the License at
12 * http://www.mozilla.org/MPL/
14 * Software distributed under the License is distributed on an "AS IS" basis,
15 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
16 * for the specific language governing rights and limitations under the
19 * The Original Code is the Nice GLib ICE library.
21 * The Initial Developers of the Original Code are Collabora Ltd and Nokia
22 * Corporation. All Rights Reserved.
25 * Dafydd Harries, Collabora Ltd.
26 * Youness Alaoui, Collabora Ltd.
29 * Alternatively, the contents of this file may be used under the terms of the
30 * the GNU Lesser General Public License Version 2.1 (the "LGPL"), in which
31 * case the provisions of LGPL are applicable instead of those above. If you
32 * wish to allow use of your version of this file only under the terms of the
33 * LGPL and not to allow others to use your version of this file under the
34 * MPL, indicate your decision by deleting the provisions above and replace
35 * them with the notice and other provisions required by the LGPL. If you do
36 * not delete the provisions above, a recipient may use your version of this
37 * file under either the MPL or the LGPL.
42 #define NICEAPI_EXPORT
50 #define inet_pton inet_pton_win32
51 #define inet_ntop inet_ntop_win32
55 inet_ntop_win32 (int af
, const void *src
, char *dst
, socklen_t cnt
)
58 struct sockaddr_in in
;
59 memset(&in
, 0, sizeof(in
));
60 in
.sin_family
= AF_INET
;
61 memcpy(&in
.sin_addr
, src
, sizeof(struct in_addr
));
62 getnameinfo((struct sockaddr
*)&in
, sizeof(struct sockaddr_in
),
63 dst
, cnt
, NULL
, 0, NI_NUMERICHOST
);
65 } else if (af
== AF_INET6
) {
66 struct sockaddr_in6 in
;
67 memset(&in
, 0, sizeof(in
));
68 in
.sin6_family
= AF_INET6
;
69 memcpy(&in
.sin6_addr
, src
, sizeof(struct in_addr6
));
70 getnameinfo((struct sockaddr
*)&in
, sizeof(struct sockaddr_in6
),
71 dst
, cnt
, NULL
, 0, NI_NUMERICHOST
);
78 inet_pton_win32(int af
, const char *src
, void *dst
)
80 struct addrinfo hints
, *res
, *ressave
;
82 memset(&hints
, 0, sizeof(struct addrinfo
));
85 if (getaddrinfo(src
, NULL
, &hints
, &res
) != 0) {
92 if( res
->ai_addr
->sa_family
== AF_INET
) {
93 memcpy(dst
, &((struct sockaddr_in
*) res
->ai_addr
)->sin_addr
,
96 } else if(res
->ai_addr
->sa_family
== AF_INET6
) {
97 memcpy(dst
, &((struct sockaddr_in6
*) res
->ai_addr
)->sin6_addr
,
103 freeaddrinfo(ressave
);
112 nice_address_init (NiceAddress
*addr
)
114 addr
->s
.addr
.sa_family
= AF_UNSPEC
;
115 memset (&addr
->s
, 0, sizeof(addr
->s
));
118 NICEAPI_EXPORT NiceAddress
*
119 nice_address_new (void)
121 NiceAddress
*addr
= g_slice_new0 (NiceAddress
);
122 nice_address_init (addr
);
128 nice_address_set_ipv4 (NiceAddress
*addr
, guint32 addr_ipv4
)
130 addr
->s
.ip4
.sin_family
= AF_INET
;
132 addr
->s
.ip4
.sin_len
= sizeof (addr
->sa
.ip4
);
134 addr
->s
.ip4
.sin_addr
.s_addr
= addr_ipv4
? htonl (addr_ipv4
) : INADDR_ANY
;
135 addr
->s
.ip4
.sin_port
= 0;
140 nice_address_set_ipv6 (NiceAddress
*addr
, const guchar
*addr_ipv6
)
142 addr
->s
.ip6
.sin6_family
= AF_INET6
;
144 addr
->s
.ip6
.sin6_len
= sizeof (addr
->sa
.ip6
);
146 memcpy (addr
->s
.ip6
.sin6_addr
.s6_addr
, addr_ipv6
, 16);
147 addr
->s
.ip6
.sin6_port
= addr
->s
.ip6
.sin6_scope_id
= 0;
152 nice_address_set_port (NiceAddress
*addr
, guint port
)
156 switch (addr
->s
.addr
.sa_family
)
159 addr
->s
.ip4
.sin_port
= htons (port
);
162 addr
->s
.ip6
.sin6_port
= htons (port
);
165 g_return_if_reached ();
171 nice_address_get_port (const NiceAddress
*addr
)
176 switch (addr
->s
.addr
.sa_family
)
179 return ntohs (addr
->s
.ip4
.sin_port
);
181 return ntohs (addr
->s
.ip6
.sin6_port
);
184 g_return_val_if_reached (0);
188 NICEAPI_EXPORT gboolean
189 nice_address_set_from_string (NiceAddress
*addr
, const gchar
*str
)
194 struct in6_addr ipv6
;
197 if (inet_pton (AF_INET
, str
, &a
.ipv4
) > 0)
198 nice_address_set_ipv4 (addr
, ntohl (a
.ipv4
.s_addr
));
199 else if (inet_pton (AF_INET6
, str
, &a
.ipv6
) > 0)
200 nice_address_set_ipv6 (addr
, a
.ipv6
.s6_addr
);
202 return FALSE
; /* Invalid address */
209 nice_address_set_from_sockaddr (NiceAddress
*addr
,
210 const struct sockaddr
*sa
)
212 switch (sa
->sa_family
)
215 memcpy(&addr
->s
.ip4
, sa
, sizeof (addr
->s
.ip4
));
218 memcpy(&addr
->s
.ip6
, sa
, sizeof (addr
->s
.ip6
));
221 g_return_if_reached ();
227 nice_address_copy_to_sockaddr (const NiceAddress
*addr
,
230 struct sockaddr_in
*sin4
= (struct sockaddr_in
*)sa
;
231 struct sockaddr_in6
*sin6
= (struct sockaddr_in6
*)sa
;
235 switch (addr
->s
.addr
.sa_family
)
238 memcpy (sin4
, &addr
->s
.ip4
, sizeof (*sin4
));
241 memcpy (sin6
, &addr
->s
.ip6
, sizeof (*sin6
));
244 g_return_if_reached ();
249 nice_address_to_string (const NiceAddress
*addr
, gchar
*dst
)
251 switch (addr
->s
.addr
.sa_family
) {
253 inet_ntop (AF_INET
, &addr
->s
.ip4
.sin_addr
, dst
, INET_ADDRSTRLEN
);
256 inet_ntop (AF_INET6
, &addr
->s
.ip6
.sin6_addr
, dst
, INET6_ADDRSTRLEN
);
259 g_return_if_reached ();
264 NICEAPI_EXPORT gboolean
265 nice_address_equal (const NiceAddress
*a
, const NiceAddress
*b
)
267 if (a
->s
.addr
.sa_family
!= b
->s
.addr
.sa_family
)
270 switch (a
->s
.addr
.sa_family
)
273 return (a
->s
.ip4
.sin_addr
.s_addr
== b
->s
.ip4
.sin_addr
.s_addr
)
274 && (a
->s
.ip4
.sin_port
== b
->s
.ip4
.sin_port
);
277 return IN6_ARE_ADDR_EQUAL (&a
->s
.ip6
.sin6_addr
, &b
->s
.ip6
.sin6_addr
)
278 && (a
->s
.ip6
.sin6_port
== b
->s
.ip6
.sin6_port
)
279 && (a
->s
.ip6
.sin6_scope_id
== b
->s
.ip6
.sin6_scope_id
);
282 g_return_val_if_reached (FALSE
);
286 NICEAPI_EXPORT NiceAddress
*
287 nice_address_dup (const NiceAddress
*a
)
289 NiceAddress
*dup
= g_slice_new0 (NiceAddress
);
297 nice_address_free (NiceAddress
*addr
)
299 g_slice_free (NiceAddress
, addr
);
303 /* "private" in the sense of "not routable on the Internet" */
305 ipv4_address_is_private (guint32 addr
)
309 /* http://tools.ietf.org/html/rfc3330 */
312 ((addr
& 0xff000000) == 0x0a000000) ||
314 ((addr
& 0xfff00000) == 0xac100000) ||
316 ((addr
& 0xffff0000) == 0xc0a80000) ||
318 ((addr
& 0xff000000) == 0x7f000000));
323 ipv6_address_is_private (const guchar
*addr
)
327 ((addr
[0] == 0xfe) && ((addr
[1] & 0xc) == 0x80)) ||
329 ((addr
[0] & 0xfe) == 0xfc) ||
331 ((memcmp (addr
, "\x00\x00\x00\x00"
334 "\x00\x00\x00\x01", 16) == 0)));
338 NICEAPI_EXPORT gboolean
339 nice_address_is_private (const NiceAddress
*a
)
341 switch (a
->s
.addr
.sa_family
)
344 return ipv4_address_is_private (a
->s
.ip4
.sin_addr
.s_addr
);
346 return ipv6_address_is_private (a
->s
.ip6
.sin6_addr
.s6_addr
);
349 g_return_val_if_reached (FALSE
);
353 NICEAPI_EXPORT gboolean
354 nice_address_is_valid (const NiceAddress
*a
)
356 switch (a
->s
.addr
.sa_family
)