1 /* GIO - GLib Input, Output and Streaming Library
3 * Copyright (C) 2008 Christian Kellner, Samuel Cormier-Iijima
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.
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.
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.
20 * Authors: Christian Kellner <gicmo@gnome.org>
21 * Samuel Cormier-Iijima <sciyoshi@gmail.com>
30 #include "ginetaddress.h"
32 #include "gioenumtypes.h"
34 #include "gnetworkingprivate.h"
38 * SECTION:ginetaddress
39 * @short_description: An IPv4/IPv6 address
41 * #GInetAddress represents an IPv4 or IPv6 internet address. Use
42 * g_resolver_lookup_by_name() or g_resolver_lookup_by_name_async() to
43 * look up the #GInetAddress for a hostname. Use
44 * g_resolver_lookup_by_address() or
45 * g_resolver_lookup_by_address_async() to look up the hostname for a
48 * To actually connect to a remote host, you will need a
49 * #GInetSocketAddress (which includes a #GInetAddress as well as a
56 * An IPv4 or IPv6 internet address.
59 G_DEFINE_TYPE_WITH_CODE (GInetAddress, g_inet_address, G_TYPE_OBJECT,
60 g_networking_init ();)
62 struct _GInetAddressPrivate
82 PROP_IS_MC_LINK_LOCAL,
83 PROP_IS_MC_NODE_LOCAL,
85 PROP_IS_MC_SITE_LOCAL,
89 g_inet_address_set_property (GObject *object,
94 GInetAddress *address = G_INET_ADDRESS (object);
99 address->priv->family = g_value_get_enum (value);
103 memcpy (&address->priv->addr, g_value_get_pointer (value),
104 address->priv->family == AF_INET ?
105 sizeof (address->priv->addr.ipv4) :
106 sizeof (address->priv->addr.ipv6));
110 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
117 g_inet_address_get_property (GObject *object,
122 GInetAddress *address = G_INET_ADDRESS (object);
127 g_value_set_enum (value, address->priv->family);
131 g_value_set_pointer (value, &address->priv->addr);
135 g_value_set_boolean (value, g_inet_address_get_is_any (address));
138 case PROP_IS_LOOPBACK:
139 g_value_set_boolean (value, g_inet_address_get_is_loopback (address));
142 case PROP_IS_LINK_LOCAL:
143 g_value_set_boolean (value, g_inet_address_get_is_link_local (address));
146 case PROP_IS_SITE_LOCAL:
147 g_value_set_boolean (value, g_inet_address_get_is_site_local (address));
150 case PROP_IS_MULTICAST:
151 g_value_set_boolean (value, g_inet_address_get_is_multicast (address));
154 case PROP_IS_MC_GLOBAL:
155 g_value_set_boolean (value, g_inet_address_get_is_mc_global (address));
158 case PROP_IS_MC_LINK_LOCAL:
159 g_value_set_boolean (value, g_inet_address_get_is_mc_link_local (address));
162 case PROP_IS_MC_NODE_LOCAL:
163 g_value_set_boolean (value, g_inet_address_get_is_mc_node_local (address));
166 case PROP_IS_MC_ORG_LOCAL:
167 g_value_set_boolean (value, g_inet_address_get_is_mc_org_local (address));
170 case PROP_IS_MC_SITE_LOCAL:
171 g_value_set_boolean (value, g_inet_address_get_is_mc_site_local (address));
175 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
180 g_inet_address_class_init (GInetAddressClass *klass)
182 GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
184 g_type_class_add_private (klass, sizeof (GInetAddressPrivate));
186 gobject_class->set_property = g_inet_address_set_property;
187 gobject_class->get_property = g_inet_address_get_property;
189 g_object_class_install_property (gobject_class, PROP_FAMILY,
190 g_param_spec_enum ("family",
191 P_("Address family"),
192 P_("The address family (IPv4 or IPv6)"),
193 G_TYPE_SOCKET_FAMILY,
194 G_SOCKET_FAMILY_INVALID,
196 G_PARAM_CONSTRUCT_ONLY |
197 G_PARAM_STATIC_STRINGS));
199 g_object_class_install_property (gobject_class, PROP_BYTES,
200 g_param_spec_pointer ("bytes",
202 P_("The raw address data"),
204 G_PARAM_CONSTRUCT_ONLY |
205 G_PARAM_STATIC_STRINGS));
208 * GInetAddress:is-any:
210 * Whether this is the "any" address for its family.
211 * See g_inet_address_get_is_any().
215 g_object_class_install_property (gobject_class, PROP_IS_ANY,
216 g_param_spec_boolean ("is-any",
218 P_("Whether this is the \"any\" address for its family"),
221 G_PARAM_STATIC_STRINGS));
224 * GInetAddress:is-link-local:
226 * Whether this is a link-local address.
227 * See g_inet_address_get_is_link_local().
231 g_object_class_install_property (gobject_class, PROP_IS_LINK_LOCAL,
232 g_param_spec_boolean ("is-link-local",
234 P_("Whether this is a link-local address"),
237 G_PARAM_STATIC_STRINGS));
240 * GInetAddress:is-loopback:
242 * Whether this is the loopback address for its family.
243 * See g_inet_address_get_is_loopback().
247 g_object_class_install_property (gobject_class, PROP_IS_LOOPBACK,
248 g_param_spec_boolean ("is-loopback",
250 P_("Whether this is the loopback address for its family"),
253 G_PARAM_STATIC_STRINGS));
256 * GInetAddress:is-site-local:
258 * Whether this is a site-local address.
259 * See g_inet_address_get_is_loopback().
263 g_object_class_install_property (gobject_class, PROP_IS_SITE_LOCAL,
264 g_param_spec_boolean ("is-site-local",
266 P_("Whether this is a site-local address"),
269 G_PARAM_STATIC_STRINGS));
272 * GInetAddress:is-multicast:
274 * Whether this is a multicast address.
275 * See g_inet_address_get_is_multicast().
279 g_object_class_install_property (gobject_class, PROP_IS_MULTICAST,
280 g_param_spec_boolean ("is-multicast",
282 P_("Whether this is a multicast address"),
285 G_PARAM_STATIC_STRINGS));
288 * GInetAddress:is-mc-global:
290 * Whether this is a global multicast address.
291 * See g_inet_address_get_is_mc_global().
295 g_object_class_install_property (gobject_class, PROP_IS_MC_GLOBAL,
296 g_param_spec_boolean ("is-mc-global",
297 P_("Is multicast global"),
298 P_("Whether this is a global multicast address"),
301 G_PARAM_STATIC_STRINGS));
305 * GInetAddress:is-mc-link-local:
307 * Whether this is a link-local multicast address.
308 * See g_inet_address_get_is_mc_link_local().
312 g_object_class_install_property (gobject_class, PROP_IS_MC_LINK_LOCAL,
313 g_param_spec_boolean ("is-mc-link-local",
314 P_("Is multicast link-local"),
315 P_("Whether this is a link-local multicast address"),
318 G_PARAM_STATIC_STRINGS));
321 * GInetAddress:is-mc-node-local:
323 * Whether this is a node-local multicast address.
324 * See g_inet_address_get_is_mc_node_local().
328 g_object_class_install_property (gobject_class, PROP_IS_MC_NODE_LOCAL,
329 g_param_spec_boolean ("is-mc-node-local",
330 P_("Is multicast node-local"),
331 P_("Whether this is a node-local multicast address"),
334 G_PARAM_STATIC_STRINGS));
337 * GInetAddress:is-mc-org-local:
339 * Whether this is an organization-local multicast address.
340 * See g_inet_address_get_is_mc_org_local().
344 g_object_class_install_property (gobject_class, PROP_IS_MC_ORG_LOCAL,
345 g_param_spec_boolean ("is-mc-org-local",
346 P_("Is multicast org-local"),
347 P_("Whether this is an organization-local multicast address"),
350 G_PARAM_STATIC_STRINGS));
353 * GInetAddress:is-mc-site-local:
355 * Whether this is a site-local multicast address.
356 * See g_inet_address_get_is_mc_site_local().
360 g_object_class_install_property (gobject_class, PROP_IS_MC_SITE_LOCAL,
361 g_param_spec_boolean ("is-mc-site-local",
362 P_("Is multicast site-local"),
363 P_("Whether this is a site-local multicast address"),
366 G_PARAM_STATIC_STRINGS));
370 g_inet_address_init (GInetAddress *address)
372 address->priv = G_TYPE_INSTANCE_GET_PRIVATE (address,
374 GInetAddressPrivate);
378 * g_inet_address_new_from_string:
379 * @string: a string representation of an IP address
381 * Parses @string as an IP address and creates a new #GInetAddress.
383 * Returns: a new #GInetAddress corresponding to @string, or %NULL if
384 * @string could not be parsed.
389 g_inet_address_new_from_string (const gchar *string)
392 struct sockaddr_storage sa;
393 struct sockaddr_in *sin = (struct sockaddr_in *)&sa;
394 struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)&sa;
396 #else /* !G_OS_WIN32 */
397 struct in_addr in_addr;
398 struct in6_addr in6_addr;
401 /* If this GInetAddress is the first networking-related object to be
402 * created, then we won't have called g_networking_init() yet at
405 g_networking_init ();
408 memset (&sa, 0, sizeof (sa));
410 if (WSAStringToAddress ((LPTSTR) string, AF_INET, NULL, (LPSOCKADDR) &sa, &len) == 0)
411 return g_inet_address_new_from_bytes ((guint8 *)&sin->sin_addr, AF_INET);
412 else if (WSAStringToAddress ((LPTSTR) string, AF_INET6, NULL, (LPSOCKADDR) &sa, &len) == 0)
413 return g_inet_address_new_from_bytes ((guint8 *)&sin6->sin6_addr, AF_INET6);
415 #else /* !G_OS_WIN32 */
417 if (inet_pton (AF_INET, string, &in_addr) > 0)
418 return g_inet_address_new_from_bytes ((guint8 *)&in_addr, AF_INET);
419 else if (inet_pton (AF_INET6, string, &in6_addr) > 0)
420 return g_inet_address_new_from_bytes ((guint8 *)&in6_addr, AF_INET6);
426 #define G_INET_ADDRESS_FAMILY_IS_VALID(family) ((family) == AF_INET || (family) == AF_INET6)
429 * g_inet_address_new_from_bytes:
430 * @bytes: (array) (element-type guint8): raw address data
431 * @family: the address family of @bytes
433 * Creates a new #GInetAddress from the given @family and @bytes.
434 * @bytes should be 4 bytes for %G_SOCKET_FAMILY_IPV4 and 16 bytes for
435 * %G_SOCKET_FAMILY_IPV6.
437 * Returns: a new #GInetAddress corresponding to @family and @bytes.
442 g_inet_address_new_from_bytes (const guint8 *bytes,
443 GSocketFamily family)
445 g_return_val_if_fail (G_INET_ADDRESS_FAMILY_IS_VALID (family), NULL);
447 return g_object_new (G_TYPE_INET_ADDRESS,
454 * g_inet_address_new_loopback:
455 * @family: the address family
457 * Creates a #GInetAddress for the loopback address for @family.
459 * Returns: a new #GInetAddress corresponding to the loopback address
465 g_inet_address_new_loopback (GSocketFamily family)
467 g_return_val_if_fail (G_INET_ADDRESS_FAMILY_IS_VALID (family), NULL);
469 if (family == AF_INET)
471 guint8 addr[4] = {127, 0, 0, 1};
473 return g_inet_address_new_from_bytes (addr, family);
476 return g_inet_address_new_from_bytes (in6addr_loopback.s6_addr, family);
480 * g_inet_address_new_any:
481 * @family: the address family
483 * Creates a #GInetAddress for the "any" address (unassigned/"don't
484 * care") for @family.
486 * Returns: a new #GInetAddress corresponding to the "any" address
492 g_inet_address_new_any (GSocketFamily family)
494 g_return_val_if_fail (G_INET_ADDRESS_FAMILY_IS_VALID (family), NULL);
496 if (family == AF_INET)
498 guint8 addr[4] = {0, 0, 0, 0};
500 return g_inet_address_new_from_bytes (addr, family);
503 return g_inet_address_new_from_bytes (in6addr_any.s6_addr, family);
508 * g_inet_address_to_string:
509 * @address: a #GInetAddress
511 * Converts @address to string form.
513 * Returns: a representation of @address as a string, which should be
519 g_inet_address_to_string (GInetAddress *address)
521 gchar buffer[INET6_ADDRSTRLEN];
523 DWORD buflen = sizeof (buffer), addrlen;
524 struct sockaddr_storage sa;
525 struct sockaddr_in *sin = (struct sockaddr_in *)&sa;
526 struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)&sa;
529 g_return_val_if_fail (G_IS_INET_ADDRESS (address), NULL);
532 sa.ss_family = address->priv->family;
533 if (address->priv->family == AF_INET)
535 addrlen = sizeof (*sin);
536 memcpy (&sin->sin_addr, &address->priv->addr.ipv4,
537 sizeof (sin->sin_addr));
542 addrlen = sizeof (*sin6);
543 memcpy (&sin6->sin6_addr, &address->priv->addr.ipv6,
544 sizeof (sin6->sin6_addr));
547 if (WSAAddressToString ((LPSOCKADDR) &sa, addrlen, NULL, buffer, &buflen) != 0)
550 #else /* !G_OS_WIN32 */
552 if (address->priv->family == AF_INET)
553 inet_ntop (AF_INET, &address->priv->addr.ipv4, buffer, sizeof (buffer));
555 inet_ntop (AF_INET6, &address->priv->addr.ipv6, buffer, sizeof (buffer));
558 return g_strdup (buffer);
562 * g_inet_address_to_bytes: (skip)
563 * @address: a #GInetAddress
565 * Gets the raw binary address data from @address.
567 * Returns: a pointer to an internal array of the bytes in @address,
568 * which should not be modified, stored, or freed. The size of this
569 * array can be gotten with g_inet_address_get_native_size().
574 g_inet_address_to_bytes (GInetAddress *address)
576 g_return_val_if_fail (G_IS_INET_ADDRESS (address), NULL);
578 return (guint8 *)&address->priv->addr;
582 * g_inet_address_get_native_size:
583 * @address: a #GInetAddress
585 * Gets the size of the native raw binary address for @address. This
586 * is the size of the data that you get from g_inet_address_to_bytes().
588 * Returns: the number of bytes used for the native version of @address.
593 g_inet_address_get_native_size (GInetAddress *address)
595 if (address->priv->family == AF_INET)
596 return sizeof (address->priv->addr.ipv4);
597 return sizeof (address->priv->addr.ipv6);
601 * g_inet_address_get_family:
602 * @address: a #GInetAddress
604 * Gets @address's family
606 * Returns: @address's family
611 g_inet_address_get_family (GInetAddress *address)
613 g_return_val_if_fail (G_IS_INET_ADDRESS (address), FALSE);
615 return address->priv->family;
619 * g_inet_address_get_is_any:
620 * @address: a #GInetAddress
622 * Tests whether @address is the "any" address for its family.
624 * Returns: %TRUE if @address is the "any" address for its family.
629 g_inet_address_get_is_any (GInetAddress *address)
631 g_return_val_if_fail (G_IS_INET_ADDRESS (address), FALSE);
633 if (address->priv->family == AF_INET)
635 guint32 addr4 = g_ntohl (address->priv->addr.ipv4.s_addr);
637 return addr4 == INADDR_ANY;
640 return IN6_IS_ADDR_UNSPECIFIED (&address->priv->addr.ipv6);
644 * g_inet_address_get_is_loopback:
645 * @address: a #GInetAddress
647 * Tests whether @address is the loopback address for its family.
649 * Returns: %TRUE if @address is the loopback address for its family.
654 g_inet_address_get_is_loopback (GInetAddress *address)
656 g_return_val_if_fail (G_IS_INET_ADDRESS (address), FALSE);
658 if (address->priv->family == AF_INET)
660 guint32 addr4 = g_ntohl (address->priv->addr.ipv4.s_addr);
663 return ((addr4 & 0xff000000) == 0x7f000000);
666 return IN6_IS_ADDR_LOOPBACK (&address->priv->addr.ipv6);
670 * g_inet_address_get_is_link_local:
671 * @address: a #GInetAddress
673 * Tests whether @address is a link-local address (that is, if it
674 * identifies a host on a local network that is not connected to the
677 * Returns: %TRUE if @address is a link-local address.
682 g_inet_address_get_is_link_local (GInetAddress *address)
684 g_return_val_if_fail (G_IS_INET_ADDRESS (address), FALSE);
686 if (address->priv->family == AF_INET)
688 guint32 addr4 = g_ntohl (address->priv->addr.ipv4.s_addr);
691 return ((addr4 & 0xffff0000) == 0xa9fe0000);
694 return IN6_IS_ADDR_LINKLOCAL (&address->priv->addr.ipv6);
698 * g_inet_address_get_is_site_local:
699 * @address: a #GInetAddress
701 * Tests whether @address is a site-local address such as 10.0.0.1
702 * (that is, the address identifies a host on a local network that can
703 * not be reached directly from the Internet, but which may have
704 * outgoing Internet connectivity via a NAT or firewall).
706 * Returns: %TRUE if @address is a site-local address.
711 g_inet_address_get_is_site_local (GInetAddress *address)
713 g_return_val_if_fail (G_IS_INET_ADDRESS (address), FALSE);
715 if (address->priv->family == AF_INET)
717 guint32 addr4 = g_ntohl (address->priv->addr.ipv4.s_addr);
719 /* 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16 */
720 return ((addr4 & 0xff000000) == 0x0a000000 ||
721 (addr4 & 0xfff00000) == 0xac100000 ||
722 (addr4 & 0xffff0000) == 0xc0a80000);
725 return IN6_IS_ADDR_SITELOCAL (&address->priv->addr.ipv6);
729 * g_inet_address_get_is_multicast:
730 * @address: a #GInetAddress
732 * Tests whether @address is a multicast address.
734 * Returns: %TRUE if @address is a multicast address.
739 g_inet_address_get_is_multicast (GInetAddress *address)
741 g_return_val_if_fail (G_IS_INET_ADDRESS (address), FALSE);
743 if (address->priv->family == AF_INET)
745 guint32 addr4 = g_ntohl (address->priv->addr.ipv4.s_addr);
747 return IN_MULTICAST (addr4);
750 return IN6_IS_ADDR_MULTICAST (&address->priv->addr.ipv6);
754 * g_inet_address_get_is_mc_global:
755 * @address: a #GInetAddress
757 * Tests whether @address is a global multicast address.
759 * Returns: %TRUE if @address is a global multicast address.
764 g_inet_address_get_is_mc_global (GInetAddress *address)
766 g_return_val_if_fail (G_IS_INET_ADDRESS (address), FALSE);
768 if (address->priv->family == AF_INET)
771 return IN6_IS_ADDR_MC_GLOBAL (&address->priv->addr.ipv6);
775 * g_inet_address_get_is_mc_link_local:
776 * @address: a #GInetAddress
778 * Tests whether @address is a link-local multicast address.
780 * Returns: %TRUE if @address is a link-local multicast address.
785 g_inet_address_get_is_mc_link_local (GInetAddress *address)
787 g_return_val_if_fail (G_IS_INET_ADDRESS (address), FALSE);
789 if (address->priv->family == AF_INET)
792 return IN6_IS_ADDR_MC_LINKLOCAL (&address->priv->addr.ipv6);
796 * g_inet_address_get_is_mc_node_local:
797 * @address: a #GInetAddress
799 * Tests whether @address is a node-local multicast address.
801 * Returns: %TRUE if @address is a node-local multicast address.
806 g_inet_address_get_is_mc_node_local (GInetAddress *address)
808 g_return_val_if_fail (G_IS_INET_ADDRESS (address), FALSE);
810 if (address->priv->family == AF_INET)
813 return IN6_IS_ADDR_MC_NODELOCAL (&address->priv->addr.ipv6);
817 * g_inet_address_get_is_mc_org_local:
818 * @address: a #GInetAddress
820 * Tests whether @address is an organization-local multicast address.
822 * Returns: %TRUE if @address is an organization-local multicast address.
827 g_inet_address_get_is_mc_org_local (GInetAddress *address)
829 g_return_val_if_fail (G_IS_INET_ADDRESS (address), FALSE);
831 if (address->priv->family == AF_INET)
834 return IN6_IS_ADDR_MC_ORGLOCAL (&address->priv->addr.ipv6);
838 * g_inet_address_get_is_mc_site_local:
839 * @address: a #GInetAddress
841 * Tests whether @address is a site-local multicast address.
843 * Returns: %TRUE if @address is a site-local multicast address.
848 g_inet_address_get_is_mc_site_local (GInetAddress *address)
850 g_return_val_if_fail (G_IS_INET_ADDRESS (address), FALSE);
852 if (address->priv->family == AF_INET)
855 return IN6_IS_ADDR_MC_SITELOCAL (&address->priv->addr.ipv6);
859 * g_inet_address_equal:
860 * @address: A #GInetAddress.
861 * @other_address: Another #GInetAddress.
863 * Checks if two #GInetAddress instances are equal, e.g. the same address.
865 * Returns: %TRUE if @address and @other_address are equal, %FALSE otherwise.
870 g_inet_address_equal (GInetAddress *address,
871 GInetAddress *other_address)
873 g_return_val_if_fail (G_IS_INET_ADDRESS (address), FALSE);
874 g_return_val_if_fail (G_IS_INET_ADDRESS (other_address), FALSE);
876 if (g_inet_address_get_family (address) != g_inet_address_get_family (other_address))
879 if (memcmp (g_inet_address_to_bytes (address),
880 g_inet_address_to_bytes (other_address),
881 g_inet_address_get_native_size (address)) != 0)