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 /* We need to make sure to not pass a string of the form
409 * "IPv4addr:port" or "[IPv6addr]:port" to WSAStringToAddress(),
410 * since it would accept them (returning both the address and the
411 * port), but we only want to accept standalone IP addresses. (In
412 * the IPv6 case, WINE actually only checks for the ']', not the
413 * '[', which is why we do the same here.)
415 if (!strchr (string, ':'))
418 if (WSAStringToAddress ((LPTSTR) string, AF_INET, NULL, (LPSOCKADDR) &sa, &len) == 0)
419 return g_inet_address_new_from_bytes ((guint8 *)&sin->sin_addr, AF_INET);
422 if (!strchr (string, ']'))
425 if (WSAStringToAddress ((LPTSTR) string, AF_INET6, NULL, (LPSOCKADDR) &sa, &len) == 0)
426 return g_inet_address_new_from_bytes ((guint8 *)&sin6->sin6_addr, AF_INET6);
429 #else /* !G_OS_WIN32 */
431 if (inet_pton (AF_INET, string, &in_addr) > 0)
432 return g_inet_address_new_from_bytes ((guint8 *)&in_addr, AF_INET);
433 else if (inet_pton (AF_INET6, string, &in6_addr) > 0)
434 return g_inet_address_new_from_bytes ((guint8 *)&in6_addr, AF_INET6);
440 #define G_INET_ADDRESS_FAMILY_IS_VALID(family) ((family) == AF_INET || (family) == AF_INET6)
443 * g_inet_address_new_from_bytes:
444 * @bytes: (array) (element-type guint8): raw address data
445 * @family: the address family of @bytes
447 * Creates a new #GInetAddress from the given @family and @bytes.
448 * @bytes should be 4 bytes for %G_SOCKET_FAMILY_IPV4 and 16 bytes for
449 * %G_SOCKET_FAMILY_IPV6.
451 * Returns: a new #GInetAddress corresponding to @family and @bytes.
456 g_inet_address_new_from_bytes (const guint8 *bytes,
457 GSocketFamily family)
459 g_return_val_if_fail (G_INET_ADDRESS_FAMILY_IS_VALID (family), NULL);
461 return g_object_new (G_TYPE_INET_ADDRESS,
468 * g_inet_address_new_loopback:
469 * @family: the address family
471 * Creates a #GInetAddress for the loopback address for @family.
473 * Returns: a new #GInetAddress corresponding to the loopback address
479 g_inet_address_new_loopback (GSocketFamily family)
481 g_return_val_if_fail (G_INET_ADDRESS_FAMILY_IS_VALID (family), NULL);
483 if (family == AF_INET)
485 guint8 addr[4] = {127, 0, 0, 1};
487 return g_inet_address_new_from_bytes (addr, family);
490 return g_inet_address_new_from_bytes (in6addr_loopback.s6_addr, family);
494 * g_inet_address_new_any:
495 * @family: the address family
497 * Creates a #GInetAddress for the "any" address (unassigned/"don't
498 * care") for @family.
500 * Returns: a new #GInetAddress corresponding to the "any" address
506 g_inet_address_new_any (GSocketFamily family)
508 g_return_val_if_fail (G_INET_ADDRESS_FAMILY_IS_VALID (family), NULL);
510 if (family == AF_INET)
512 guint8 addr[4] = {0, 0, 0, 0};
514 return g_inet_address_new_from_bytes (addr, family);
517 return g_inet_address_new_from_bytes (in6addr_any.s6_addr, family);
522 * g_inet_address_to_string:
523 * @address: a #GInetAddress
525 * Converts @address to string form.
527 * Returns: a representation of @address as a string, which should be
533 g_inet_address_to_string (GInetAddress *address)
535 gchar buffer[INET6_ADDRSTRLEN];
537 DWORD buflen = sizeof (buffer), addrlen;
538 struct sockaddr_storage sa;
539 struct sockaddr_in *sin = (struct sockaddr_in *)&sa;
540 struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)&sa;
543 g_return_val_if_fail (G_IS_INET_ADDRESS (address), NULL);
546 memset (&sa, 0, sizeof (sa));
547 sa.ss_family = address->priv->family;
548 if (address->priv->family == AF_INET)
550 addrlen = sizeof (*sin);
551 memcpy (&sin->sin_addr, &address->priv->addr.ipv4,
552 sizeof (sin->sin_addr));
556 addrlen = sizeof (*sin6);
557 memcpy (&sin6->sin6_addr, &address->priv->addr.ipv6,
558 sizeof (sin6->sin6_addr));
560 if (WSAAddressToString ((LPSOCKADDR) &sa, addrlen, NULL, buffer, &buflen) != 0)
563 #else /* !G_OS_WIN32 */
565 if (address->priv->family == AF_INET)
566 inet_ntop (AF_INET, &address->priv->addr.ipv4, buffer, sizeof (buffer));
568 inet_ntop (AF_INET6, &address->priv->addr.ipv6, buffer, sizeof (buffer));
571 return g_strdup (buffer);
575 * g_inet_address_to_bytes: (skip)
576 * @address: a #GInetAddress
578 * Gets the raw binary address data from @address.
580 * Returns: a pointer to an internal array of the bytes in @address,
581 * which should not be modified, stored, or freed. The size of this
582 * array can be gotten with g_inet_address_get_native_size().
587 g_inet_address_to_bytes (GInetAddress *address)
589 g_return_val_if_fail (G_IS_INET_ADDRESS (address), NULL);
591 return (guint8 *)&address->priv->addr;
595 * g_inet_address_get_native_size:
596 * @address: a #GInetAddress
598 * Gets the size of the native raw binary address for @address. This
599 * is the size of the data that you get from g_inet_address_to_bytes().
601 * Returns: the number of bytes used for the native version of @address.
606 g_inet_address_get_native_size (GInetAddress *address)
608 if (address->priv->family == AF_INET)
609 return sizeof (address->priv->addr.ipv4);
610 return sizeof (address->priv->addr.ipv6);
614 * g_inet_address_get_family:
615 * @address: a #GInetAddress
617 * Gets @address's family
619 * Returns: @address's family
624 g_inet_address_get_family (GInetAddress *address)
626 g_return_val_if_fail (G_IS_INET_ADDRESS (address), FALSE);
628 return address->priv->family;
632 * g_inet_address_get_is_any:
633 * @address: a #GInetAddress
635 * Tests whether @address is the "any" address for its family.
637 * Returns: %TRUE if @address is the "any" address for its family.
642 g_inet_address_get_is_any (GInetAddress *address)
644 g_return_val_if_fail (G_IS_INET_ADDRESS (address), FALSE);
646 if (address->priv->family == AF_INET)
648 guint32 addr4 = g_ntohl (address->priv->addr.ipv4.s_addr);
650 return addr4 == INADDR_ANY;
653 return IN6_IS_ADDR_UNSPECIFIED (&address->priv->addr.ipv6);
657 * g_inet_address_get_is_loopback:
658 * @address: a #GInetAddress
660 * Tests whether @address is the loopback address for its family.
662 * Returns: %TRUE if @address is the loopback address for its family.
667 g_inet_address_get_is_loopback (GInetAddress *address)
669 g_return_val_if_fail (G_IS_INET_ADDRESS (address), FALSE);
671 if (address->priv->family == AF_INET)
673 guint32 addr4 = g_ntohl (address->priv->addr.ipv4.s_addr);
676 return ((addr4 & 0xff000000) == 0x7f000000);
679 return IN6_IS_ADDR_LOOPBACK (&address->priv->addr.ipv6);
683 * g_inet_address_get_is_link_local:
684 * @address: a #GInetAddress
686 * Tests whether @address is a link-local address (that is, if it
687 * identifies a host on a local network that is not connected to the
690 * Returns: %TRUE if @address is a link-local address.
695 g_inet_address_get_is_link_local (GInetAddress *address)
697 g_return_val_if_fail (G_IS_INET_ADDRESS (address), FALSE);
699 if (address->priv->family == AF_INET)
701 guint32 addr4 = g_ntohl (address->priv->addr.ipv4.s_addr);
704 return ((addr4 & 0xffff0000) == 0xa9fe0000);
707 return IN6_IS_ADDR_LINKLOCAL (&address->priv->addr.ipv6);
711 * g_inet_address_get_is_site_local:
712 * @address: a #GInetAddress
714 * Tests whether @address is a site-local address such as 10.0.0.1
715 * (that is, the address identifies a host on a local network that can
716 * not be reached directly from the Internet, but which may have
717 * outgoing Internet connectivity via a NAT or firewall).
719 * Returns: %TRUE if @address is a site-local address.
724 g_inet_address_get_is_site_local (GInetAddress *address)
726 g_return_val_if_fail (G_IS_INET_ADDRESS (address), FALSE);
728 if (address->priv->family == AF_INET)
730 guint32 addr4 = g_ntohl (address->priv->addr.ipv4.s_addr);
732 /* 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16 */
733 return ((addr4 & 0xff000000) == 0x0a000000 ||
734 (addr4 & 0xfff00000) == 0xac100000 ||
735 (addr4 & 0xffff0000) == 0xc0a80000);
738 return IN6_IS_ADDR_SITELOCAL (&address->priv->addr.ipv6);
742 * g_inet_address_get_is_multicast:
743 * @address: a #GInetAddress
745 * Tests whether @address is a multicast address.
747 * Returns: %TRUE if @address is a multicast address.
752 g_inet_address_get_is_multicast (GInetAddress *address)
754 g_return_val_if_fail (G_IS_INET_ADDRESS (address), FALSE);
756 if (address->priv->family == AF_INET)
758 guint32 addr4 = g_ntohl (address->priv->addr.ipv4.s_addr);
760 return IN_MULTICAST (addr4);
763 return IN6_IS_ADDR_MULTICAST (&address->priv->addr.ipv6);
767 * g_inet_address_get_is_mc_global:
768 * @address: a #GInetAddress
770 * Tests whether @address is a global multicast address.
772 * Returns: %TRUE if @address is a global multicast address.
777 g_inet_address_get_is_mc_global (GInetAddress *address)
779 g_return_val_if_fail (G_IS_INET_ADDRESS (address), FALSE);
781 if (address->priv->family == AF_INET)
784 return IN6_IS_ADDR_MC_GLOBAL (&address->priv->addr.ipv6);
788 * g_inet_address_get_is_mc_link_local:
789 * @address: a #GInetAddress
791 * Tests whether @address is a link-local multicast address.
793 * Returns: %TRUE if @address is a link-local multicast address.
798 g_inet_address_get_is_mc_link_local (GInetAddress *address)
800 g_return_val_if_fail (G_IS_INET_ADDRESS (address), FALSE);
802 if (address->priv->family == AF_INET)
805 return IN6_IS_ADDR_MC_LINKLOCAL (&address->priv->addr.ipv6);
809 * g_inet_address_get_is_mc_node_local:
810 * @address: a #GInetAddress
812 * Tests whether @address is a node-local multicast address.
814 * Returns: %TRUE if @address is a node-local multicast address.
819 g_inet_address_get_is_mc_node_local (GInetAddress *address)
821 g_return_val_if_fail (G_IS_INET_ADDRESS (address), FALSE);
823 if (address->priv->family == AF_INET)
826 return IN6_IS_ADDR_MC_NODELOCAL (&address->priv->addr.ipv6);
830 * g_inet_address_get_is_mc_org_local:
831 * @address: a #GInetAddress
833 * Tests whether @address is an organization-local multicast address.
835 * Returns: %TRUE if @address is an organization-local multicast address.
840 g_inet_address_get_is_mc_org_local (GInetAddress *address)
842 g_return_val_if_fail (G_IS_INET_ADDRESS (address), FALSE);
844 if (address->priv->family == AF_INET)
847 return IN6_IS_ADDR_MC_ORGLOCAL (&address->priv->addr.ipv6);
851 * g_inet_address_get_is_mc_site_local:
852 * @address: a #GInetAddress
854 * Tests whether @address is a site-local multicast address.
856 * Returns: %TRUE if @address is a site-local multicast address.
861 g_inet_address_get_is_mc_site_local (GInetAddress *address)
863 g_return_val_if_fail (G_IS_INET_ADDRESS (address), FALSE);
865 if (address->priv->family == AF_INET)
868 return IN6_IS_ADDR_MC_SITELOCAL (&address->priv->addr.ipv6);
872 * g_inet_address_equal:
873 * @address: A #GInetAddress.
874 * @other_address: Another #GInetAddress.
876 * Checks if two #GInetAddress instances are equal, e.g. the same address.
878 * Returns: %TRUE if @address and @other_address are equal, %FALSE otherwise.
883 g_inet_address_equal (GInetAddress *address,
884 GInetAddress *other_address)
886 g_return_val_if_fail (G_IS_INET_ADDRESS (address), FALSE);
887 g_return_val_if_fail (G_IS_INET_ADDRESS (other_address), FALSE);
889 if (g_inet_address_get_family (address) != g_inet_address_get_family (other_address))
892 if (memcmp (g_inet_address_to_bytes (address),
893 g_inet_address_to_bytes (other_address),
894 g_inet_address_get_native_size (address)) != 0)