Add GResolver, a glib-ish interface to DNS
[platform/upstream/glib.git] / gio / ginetaddress.c
1 /* GIO - GLib Input, Output and Streaming Library
2  *
3  * Copyright (C) 2008 Christian Kellner, Samuel Cormier-Iijima
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General
16  * Public License along with this library; if not, write to the
17  * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
18  * Boston, MA 02111-1307, USA.
19  *
20  * Authors: Christian Kellner <gicmo@gnome.org>
21  *          Samuel Cormier-Iijima <sciyoshi@gmail.com>
22  */
23
24 #include <config.h>
25 #include <glib.h>
26
27 #include "ginetaddress.h"
28 #include "gioenums.h"
29 #include "gioenumtypes.h"
30 #include "glibintl.h"
31 #include "gnetworkingprivate.h"
32
33 #include "gioalias.h"
34
35 /**
36  * SECTION:ginetaddress
37  * @short_description: An IPv4/IPv6 address
38  *
39  * #GInetAddress represents an IPv4 or IPv6 internet address. Use
40  * g_resolver_lookup_by_name() or g_resolver_lookup_by_name_async() to
41  * look up the #GInetAddress for a hostname. Use
42  * g_resolver_lookup_by_address() or
43  * g_resolver_lookup_by_address_async() to look up the hostname for a
44  * #GInetAddress.
45  *
46  * To actually connect to a remote host, you will need a
47  * #GInetSocketAddress (which includes a #GInetAddress as well as a
48  * port number).
49  **/
50
51 /**
52  * GInetAddress:
53  *
54  * An IPv4 or IPv6 internet address.
55  **/
56
57 /* Networking initialization function, called from inside the g_once of
58  * g_inet_address_get_type()
59  */
60 static void
61 _g_networking_init (void)
62 {
63 #ifdef G_OS_WIN32
64   WSADATA wsadata;
65   if (WSAStartup (MAKEWORD (2, 0), &wsadata) != 0)
66     g_error ("Windows Sockets could not be initialized");
67 #endif
68 }
69
70 G_DEFINE_TYPE_WITH_CODE (GInetAddress, g_inet_address, G_TYPE_OBJECT,
71                          _g_networking_init ();)
72
73 struct _GInetAddressPrivate
74 {
75   GSocketFamily family;
76   union {
77     struct in_addr ipv4;
78     struct in6_addr ipv6;
79   } addr;
80 };
81
82 enum
83 {
84   PROP_0,
85   PROP_FAMILY,
86   PROP_BYTES,
87   PROP_IS_ANY,
88   PROP_IS_LOOPBACK,
89   PROP_IS_LINK_LOCAL,
90   PROP_IS_SITE_LOCAL,
91   PROP_IS_MULTICAST,
92   PROP_IS_MC_GLOBAL,
93   PROP_IS_MC_LINK_LOCAL,
94   PROP_IS_MC_NODE_LOCAL,
95   PROP_IS_MC_ORG_LOCAL,
96   PROP_IS_MC_SITE_LOCAL,
97 };
98
99 static void
100 g_inet_address_set_property (GObject      *object,
101                              guint         prop_id,
102                              const GValue *value,
103                              GParamSpec   *pspec)
104 {
105   GInetAddress *address = G_INET_ADDRESS (object);
106
107   switch (prop_id) 
108     {
109     case PROP_FAMILY:
110       address->priv->family = g_value_get_enum (value);
111       break;
112
113     case PROP_BYTES:
114       memcpy (&address->priv->addr, g_value_get_pointer (value),
115               address->priv->family == AF_INET ?
116               sizeof (address->priv->addr.ipv4) :
117               sizeof (address->priv->addr.ipv6));
118       break;
119
120     default:
121       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
122       break;
123     }
124
125 }
126
127 static void
128 g_inet_address_get_property (GObject    *object,
129                              guint       prop_id,
130                              GValue     *value,
131                              GParamSpec *pspec)
132 {
133   GInetAddress *address = G_INET_ADDRESS (object);
134
135   switch (prop_id)
136     {
137     case PROP_FAMILY:
138       g_value_set_enum (value, address->priv->family);
139       break;
140
141     case PROP_BYTES:
142       g_value_set_pointer (value, &address->priv->addr);
143       break;
144
145     case PROP_IS_ANY:
146       g_value_set_boolean (value, g_inet_address_get_is_any (address));
147       break;
148
149     case PROP_IS_LOOPBACK:
150       g_value_set_boolean (value, g_inet_address_get_is_loopback (address));
151       break;
152
153     case PROP_IS_LINK_LOCAL:
154       g_value_set_boolean (value, g_inet_address_get_is_link_local (address));
155       break;
156
157     case PROP_IS_SITE_LOCAL:
158       g_value_set_boolean (value, g_inet_address_get_is_site_local (address));
159       break;
160
161     case PROP_IS_MULTICAST:
162       g_value_set_boolean (value, g_inet_address_get_is_multicast (address));
163       break;
164
165     case PROP_IS_MC_GLOBAL:
166       g_value_set_boolean (value, g_inet_address_get_is_mc_global (address));
167       break;
168
169     case PROP_IS_MC_LINK_LOCAL:
170       g_value_set_boolean (value, g_inet_address_get_is_mc_link_local (address));
171       break;
172
173     case PROP_IS_MC_NODE_LOCAL:
174       g_value_set_boolean (value, g_inet_address_get_is_mc_node_local (address));
175       break;
176
177     case PROP_IS_MC_ORG_LOCAL:
178       g_value_set_boolean (value, g_inet_address_get_is_mc_org_local (address));
179       break;
180
181     case PROP_IS_MC_SITE_LOCAL:
182       g_value_set_boolean (value, g_inet_address_get_is_mc_site_local (address));
183       break;
184
185     default:
186       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
187     }
188 }
189
190 static void
191 g_inet_address_class_init (GInetAddressClass *klass)
192 {
193   GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
194
195   g_type_class_add_private (klass, sizeof (GInetAddressPrivate));
196
197   gobject_class->set_property = g_inet_address_set_property;
198   gobject_class->get_property = g_inet_address_get_property;
199
200   g_object_class_install_property (gobject_class, PROP_FAMILY,
201                                    g_param_spec_enum ("family",
202                                                       _("Address family"),
203                                                       _("The address family (IPv4 or IPv6)"),
204                                                       G_TYPE_SOCKET_FAMILY,
205                                                       G_SOCKET_FAMILY_INVALID,
206                                                       G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_STATIC_NAME));
207
208   g_object_class_install_property (gobject_class, PROP_BYTES,
209                                    g_param_spec_pointer ("bytes",
210                                                          _("Bytes"),
211                                                          _("The raw address data"),
212                                                          G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_STATIC_NAME));
213
214   g_object_class_install_property (gobject_class, PROP_IS_ANY,
215                                    g_param_spec_boolean ("is-any",
216                                                          _("Is any"),
217                                                          _("See g_inet_address_get_is_any()"),
218                                                          FALSE,
219                                                          G_PARAM_READABLE | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_STATIC_NAME));
220
221   g_object_class_install_property (gobject_class, PROP_IS_LINK_LOCAL,
222                                    g_param_spec_boolean ("is-link-local",
223                                                          _("Is link-local"),
224                                                          _("See g_inet_address_get_is_link_local()"),
225                                                          FALSE,
226                                                          G_PARAM_READABLE | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_STATIC_NAME));
227
228   g_object_class_install_property (gobject_class, PROP_IS_LOOPBACK,
229                                    g_param_spec_boolean ("is-loopback",
230                                                          _("Is loopback"),
231                                                          _("See g_inet_address_get_is_loopback()"),
232                                                          FALSE,
233                                                          G_PARAM_READABLE | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_STATIC_NAME));
234
235   g_object_class_install_property (gobject_class, PROP_IS_SITE_LOCAL,
236                                    g_param_spec_boolean ("is-site-local",
237                                                          _("Is site-local"),
238                                                          _("See g_inet_address_get_is_site_local()"),
239                                                          FALSE,
240                                                          G_PARAM_READABLE | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_STATIC_NAME));
241
242   g_object_class_install_property (gobject_class, PROP_IS_MULTICAST,
243                                    g_param_spec_boolean ("is-multicast",
244                                                          _("Is multicast"),
245                                                          _("See g_inet_address_get_is_multicast()"),
246                                                          FALSE,
247                                                          G_PARAM_READABLE | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_STATIC_NAME));
248
249   g_object_class_install_property (gobject_class, PROP_IS_MC_GLOBAL,
250                                    g_param_spec_boolean ("is-mc-global",
251                                                          _("Is multicast global"),
252                                                          _("See g_inet_address_get_is_mc_global()"),
253                                                          FALSE,
254                                                          G_PARAM_READABLE | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_STATIC_NAME));
255
256   g_object_class_install_property (gobject_class, PROP_IS_MC_LINK_LOCAL,
257                                    g_param_spec_boolean ("is-mc-link-local",
258                                                          _("Is multicast link-local"),
259                                                          _("See g_inet_address_get_is_mc_link_local()"),
260                                                          FALSE,
261                                                          G_PARAM_READABLE | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_STATIC_NAME));
262
263   g_object_class_install_property (gobject_class, PROP_IS_MC_NODE_LOCAL,
264                                    g_param_spec_boolean ("is-mc-node-local",
265                                                          _("Is multicast node-local"),
266                                                          _("See g_inet_address_get_is_mc_node_local()"),
267                                                          FALSE,
268                                                          G_PARAM_READABLE | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_STATIC_NAME));
269
270   g_object_class_install_property (gobject_class, PROP_IS_MC_ORG_LOCAL,
271                                    g_param_spec_boolean ("is-mc-org-local",
272                                                          _("Is multicast org-local"),
273                                                          _("See g_inet_address_get_is_mc_org_local()"),
274                                                          FALSE,
275                                                          G_PARAM_READABLE | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_STATIC_NAME));
276
277   g_object_class_install_property (gobject_class, PROP_IS_MC_SITE_LOCAL,
278                                    g_param_spec_boolean ("is-mc-site-local",
279                                                          _("Is multicast site-local"),
280                                                          _("See g_inet_address_get_is_mc_site_local()"),
281                                                          FALSE,
282                                                          G_PARAM_READABLE | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_STATIC_NAME));
283 }
284
285 static void
286 g_inet_address_init (GInetAddress *address)
287 {
288   address->priv = G_TYPE_INSTANCE_GET_PRIVATE (address,
289                                                G_TYPE_INET_ADDRESS,
290                                                GInetAddressPrivate);
291 }
292
293 /**
294  * g_inet_address_new_from_string:
295  * @string: a string representation of an IP address
296  *
297  * Parses @string as an IP address and creates a new #GInetAddress.
298  *
299  * Returns: a new #GInetAddress corresponding to @string, or %NULL if
300  * @string could not be parsed.
301  *
302  * Since: 2.22
303  */
304 GInetAddress *
305 g_inet_address_new_from_string (const gchar *string)
306 {
307 #ifdef G_OS_WIN32
308   struct sockaddr_storage sa;
309   struct sockaddr_in *sin = (struct sockaddr_in *)&sa;
310   struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)&sa;
311   gint len;
312 #else /* !G_OS_WIN32 */
313   struct in_addr in_addr;
314   struct in6_addr in6_addr;
315 #endif
316
317   /* Make sure _g_networking_init() has been called */
318   (void) g_inet_address_get_type ();
319
320 #ifdef G_OS_WIN32
321   memset (&sa, 0, sizeof (sa));
322   len = sizeof (sa);
323   if (WSAStringToAddress ((LPTSTR) string, AF_INET, NULL, (LPSOCKADDR) &sa, &len) == 0)
324     return g_inet_address_new_from_bytes ((guint8 *)&sin->sin_addr, AF_INET);
325   else if (WSAStringToAddress ((LPTSTR) string, AF_INET6, NULL, (LPSOCKADDR) &sa, &len) == 0)
326     return g_inet_address_new_from_bytes ((guint8 *)&sin6->sin6_addr, AF_INET6);
327
328 #else /* !G_OS_WIN32 */
329
330   if (inet_pton (AF_INET, string, &in_addr) > 0)
331     return g_inet_address_new_from_bytes ((guint8 *)&in_addr, AF_INET);
332   else if (inet_pton (AF_INET6, string, &in6_addr) > 0)
333     return g_inet_address_new_from_bytes ((guint8 *)&in6_addr, AF_INET6);
334 #endif
335
336   return NULL;
337 }
338
339 #define G_INET_ADDRESS_FAMILY_IS_VALID(family) ((family) == AF_INET || (family) == AF_INET6)
340
341 /**
342  * g_inet_address_new_from_bytes:
343  * @bytes: raw address data
344  * @family: the address family of @bytes
345  *
346  * Creates a new #GInetAddress from the given @family and @bytes.
347  * @bytes should be 4 bytes for %G_INET_ADDRESS_IPV4 and 16 bytes for
348  * %G_INET_ADDRESS_IPV6.
349  *
350  * Returns: a new #GInetAddress corresponding to @family and @bytes.
351  *
352  * Since: 2.22
353  */
354 GInetAddress *
355 g_inet_address_new_from_bytes (const guint8         *bytes,
356                                GSocketFamily  family)
357 {
358   g_return_val_if_fail (G_INET_ADDRESS_FAMILY_IS_VALID (family), NULL);
359
360   return g_object_new (G_TYPE_INET_ADDRESS,
361                        "family", family,
362                        "bytes", bytes,
363                        NULL);
364 }
365
366 /**
367  * g_inet_address_new_loopback:
368  * @family: the address family
369  *
370  * Creates a #GInetAddress for the loopback address for @family.
371  *
372  * Returns: a new #GInetAddress corresponding to the loopback address
373  * for @family.
374  *
375  * Since: 2.22
376  */
377 GInetAddress *
378 g_inet_address_new_loopback (GSocketFamily family)
379 {
380   g_return_val_if_fail (G_INET_ADDRESS_FAMILY_IS_VALID (family), NULL);
381
382   if (family == AF_INET)
383     {    
384       guint8 addr[4] = {127, 0, 0, 1};
385
386       return g_inet_address_new_from_bytes (addr, family);
387     }
388   else
389     return g_inet_address_new_from_bytes (in6addr_loopback.s6_addr, family);
390 }
391
392 /**
393  * g_inet_address_new_any:
394  * @family: the address family
395  *
396  * Creates a #GInetAddress for the "any" address (unassigned/"don't
397  * care") for @family.
398  *
399  * Returns: a new #GInetAddress corresponding to the "any" address
400  * for @family.
401  *
402  * Since: 2.22
403  */
404 GInetAddress *
405 g_inet_address_new_any (GSocketFamily family)
406 {
407   g_return_val_if_fail (G_INET_ADDRESS_FAMILY_IS_VALID (family), NULL);
408
409   if (family == AF_INET)
410     {    
411       guint8 addr[4] = {0, 0, 0, 0};
412
413       return g_inet_address_new_from_bytes (addr, family);
414     }
415   else
416     return g_inet_address_new_from_bytes (in6addr_any.s6_addr, family);
417 }
418
419
420 /**
421  * g_inet_address_to_string:
422  * @address: a #GInetAddress
423  *
424  * Converts @address to string form.
425  *
426  * Returns: a representation of @address as a string, which should be
427  * freed after use.
428  *
429  * Since: 2.22
430  */
431 gchar *
432 g_inet_address_to_string (GInetAddress *address)
433 {
434   gchar buffer[INET6_ADDRSTRLEN];
435 #ifdef G_OS_WIN32
436   DWORD buflen = sizeof (buffer), addrlen;
437   struct sockaddr_storage sa;
438   struct sockaddr_in *sin = (struct sockaddr_in *)&sa;
439   struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)&sa;
440 #endif
441
442   g_return_val_if_fail (G_IS_INET_ADDRESS (address), NULL);
443
444 #ifdef G_OS_WIN32
445   sa.ss_family = address->priv->family;
446   if (address->priv->family == AF_INET)
447     {
448       addrlen = sizeof (*sin);
449       memcpy (&sin->sin_addr, &address->priv->addr.ipv4,
450               sizeof (sin->sin_addr));
451       sin->sin_port = 0;
452     }
453   else
454     {
455       addrlen = sizeof (*sin6);
456       memcpy (&sin6->sin6_addr, &address->priv->addr.ipv6,
457               sizeof (sin6->sin6_addr));
458       sin6->sin6_port = 0;
459     }
460   if (WSAAddressToString ((LPSOCKADDR) &sa, addrlen, NULL, buffer, &buflen) != 0)
461     return NULL;
462
463 #else /* !G_OS_WIN32 */
464
465   if (address->priv->family == AF_INET)
466     inet_ntop (AF_INET, &address->priv->addr.ipv4, buffer, sizeof (buffer));
467   else
468     inet_ntop (AF_INET6, &address->priv->addr.ipv6, buffer, sizeof (buffer));
469 #endif
470
471   return g_strdup (buffer);
472 }
473
474 /**
475  * g_inet_address_to_bytes:
476  * @address: a #GInetAddress
477  *
478  * Gets the raw binary address data from @address.
479  *
480  * Returns: a pointer to an internal array of the bytes in @address,
481  * which should not be modified, stored, or freed.
482  *
483  * Since: 2.22
484  */
485 const guint8 *
486 g_inet_address_to_bytes (GInetAddress *address)
487 {
488   g_return_val_if_fail (G_IS_INET_ADDRESS (address), NULL);
489
490   return (guint8 *)&address->priv->addr;
491 }
492
493 /**
494  * g_inet_address_get_family:
495  * @address: a #GInetAddress
496  *
497  * Gets @address's family
498  *
499  * Returns: @address's family
500  *
501  * Since: 2.22
502  */
503 GSocketFamily
504 g_inet_address_get_family (GInetAddress *address)
505 {
506   g_return_val_if_fail (G_IS_INET_ADDRESS (address), FALSE);
507
508   return address->priv->family;
509 }
510
511 /**
512  * g_inet_address_get_is_any:
513  * @address: a #GInetAddress
514  *
515  * Tests whether @address is the "any" address for its family.
516  *
517  * Returns: %TRUE if @address is the "any" address for its family.
518  *
519  * Since: 2.22
520  */
521 gboolean
522 g_inet_address_get_is_any (GInetAddress *address)
523 {
524   g_return_val_if_fail (G_IS_INET_ADDRESS (address), FALSE);
525
526   if (address->priv->family == AF_INET)
527     {
528       guint32 addr4 = g_ntohl (address->priv->addr.ipv4.s_addr);
529
530       return addr4 == INADDR_ANY;
531     }
532   else
533     return IN6_IS_ADDR_UNSPECIFIED (&address->priv->addr.ipv6.s6_addr);
534 }
535
536 /**
537  * g_inet_address_get_is_loopback:
538  * @address: a #GInetAddress
539  *
540  * Tests whether @address is the loopback address for its family.
541  *
542  * Returns: %TRUE if @address is the loopback address for its family.
543  *
544  * Since: 2.22
545  */
546 gboolean
547 g_inet_address_get_is_loopback (GInetAddress *address)
548 {
549   g_return_val_if_fail (G_IS_INET_ADDRESS (address), FALSE);
550
551   if (address->priv->family == AF_INET)
552     {
553       guint32 addr4 = g_ntohl (address->priv->addr.ipv4.s_addr);
554
555       /* 127.0.0.0/8 */
556       return ((addr4 & 0xff000000) == 0x7f000000);
557     }
558   else
559     return IN6_IS_ADDR_LOOPBACK (&address->priv->addr.ipv6.s6_addr);
560 }
561
562 /**
563  * g_inet_address_get_is_link_local:
564  * @address: a #GInetAddress
565  *
566  * Tests whether @address is a link-local address (that is, if it
567  * identifies a host on a local network that is not connected to the
568  * Internet).
569  *
570  * Returns: %TRUE if @address is a link-local address.
571  *
572  * Since: 2.22
573  */
574 gboolean
575 g_inet_address_get_is_link_local (GInetAddress *address)
576 {
577   g_return_val_if_fail (G_IS_INET_ADDRESS (address), FALSE);
578
579   if (address->priv->family == AF_INET)
580     {
581       guint32 addr4 = g_ntohl (address->priv->addr.ipv4.s_addr);
582
583       /* 169.254.0.0/16 */
584       return ((addr4 & 0xffff0000) == 0xa9fe0000);
585     }
586   else
587     return IN6_IS_ADDR_LINKLOCAL (&address->priv->addr.ipv6.s6_addr);
588 }
589
590 /**
591  * g_inet_address_get_is_site_local:
592  * @address: a #GInetAddress
593  *
594  * Tests whether @address is a site-local address such as 10.0.0.1
595  * (that is, the address identifies a host on a local network that can
596  * not be reached directly from the Internet, but which may have
597  * outgoing Internet connectivity via a NAT or firewall).
598  *
599  * Returns: %TRUE if @address is a site-local address.
600  *
601  * Since: 2.22
602  */
603 gboolean
604 g_inet_address_get_is_site_local (GInetAddress *address)
605 {
606   g_return_val_if_fail (G_IS_INET_ADDRESS (address), FALSE);
607
608   if (address->priv->family == AF_INET)
609     {
610       guint32 addr4 = g_ntohl (address->priv->addr.ipv4.s_addr);
611
612       /* 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16 */
613       return ((addr4 & 0xff000000) == 0x0a000000 ||
614               (addr4 & 0xfff00000) == 0xac100000 ||
615               (addr4 & 0xffff0000) == 0xc0a80000);
616     }
617   else
618     return IN6_IS_ADDR_SITELOCAL (&address->priv->addr.ipv6.s6_addr);
619 }
620
621 /**
622  * g_inet_address_get_is_multicast:
623  * @address: a #GInetAddress
624  *
625  * Tests whether @address is a multicast address.
626  *
627  * Returns: %TRUE if @address is a multicast address.
628  *
629  * Since: 2.22
630  */
631 gboolean
632 g_inet_address_get_is_multicast (GInetAddress *address)
633 {
634   g_return_val_if_fail (G_IS_INET_ADDRESS (address), FALSE);
635
636   if (address->priv->family == AF_INET)
637     {
638       guint32 addr4 = g_ntohl (address->priv->addr.ipv4.s_addr);
639
640       return IN_MULTICAST (addr4);
641     }
642   else
643     return IN6_IS_ADDR_MULTICAST (&address->priv->addr.ipv6.s6_addr);
644 }
645
646 /**
647  * g_inet_address_get_is_mc_global:
648  * @address: a #GInetAddress
649  *
650  * Tests whether @address is a global multicast address.
651  *
652  * Returns: %TRUE if @address is a global multicast address.
653  *
654  * Since: 2.22
655  */
656 gboolean
657 g_inet_address_get_is_mc_global (GInetAddress *address)
658 {
659   g_return_val_if_fail (G_IS_INET_ADDRESS (address), FALSE);
660
661   if (address->priv->family == AF_INET)
662     return FALSE;
663   else
664     return IN6_IS_ADDR_MC_GLOBAL (&address->priv->addr.ipv6.s6_addr);
665 }
666
667 /**
668  * g_inet_address_get_is_mc_link_local:
669  * @address: a #GInetAddress
670  *
671  * Tests whether @address is a link-local multicast address.
672  *
673  * Returns: %TRUE if @address is a link-local multicast address.
674  *
675  * Since: 2.22
676  */
677 gboolean
678 g_inet_address_get_is_mc_link_local (GInetAddress *address)
679 {
680   g_return_val_if_fail (G_IS_INET_ADDRESS (address), FALSE);
681
682   if (address->priv->family == AF_INET)
683     return FALSE;
684   else
685     return IN6_IS_ADDR_MC_LINKLOCAL (&address->priv->addr.ipv6.s6_addr);
686 }
687
688 /**
689  * g_inet_address_get_is_mc_node_local:
690  * @address: a #GInetAddress
691  *
692  * Tests whether @address is a node-local multicast address.
693  *
694  * Returns: %TRUE if @address is a node-local multicast address.
695  *
696  * Since: 2.22
697  */
698 gboolean
699 g_inet_address_get_is_mc_node_local (GInetAddress *address)
700 {
701   g_return_val_if_fail (G_IS_INET_ADDRESS (address), FALSE);
702
703   if (address->priv->family == AF_INET)
704     return FALSE;
705   else
706     return IN6_IS_ADDR_MC_NODELOCAL (&address->priv->addr.ipv6.s6_addr);
707 }
708
709 /**
710  * g_inet_address_get_is_mc_org_local:
711  * @address: a #GInetAddress
712  *
713  * Tests whether @address is an organization-local multicast address.
714  *
715  * Returns: %TRUE if @address is an organization-local multicast address.
716  *
717  * Since: 2.22
718  */
719 gboolean
720 g_inet_address_get_is_mc_org_local  (GInetAddress *address)
721 {
722   g_return_val_if_fail (G_IS_INET_ADDRESS (address), FALSE);
723
724   if (address->priv->family == AF_INET)
725     return FALSE;
726   else
727     return IN6_IS_ADDR_MC_ORGLOCAL (&address->priv->addr.ipv6.s6_addr);
728 }
729
730 /**
731  * g_inet_address_get_is_mc_site_local:
732  * @address: a #GInetAddress
733  *
734  * Tests whether @address is a site-local multicast address.
735  *
736  * Returns: %TRUE if @address is a site-local multicast address.
737  *
738  * Since: 2.22
739  */
740 gboolean
741 g_inet_address_get_is_mc_site_local (GInetAddress *address)
742 {
743   g_return_val_if_fail (G_IS_INET_ADDRESS (address), FALSE);
744
745   if (address->priv->family == AF_INET)
746     return FALSE;
747   else
748     return IN6_IS_ADDR_MC_SITELOCAL (&address->priv->addr.ipv6.s6_addr);
749 }
750
751 #define __G_INET_ADDRESS_C__
752 #include "gioaliasdef.c"