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>
27 #include "ginetaddress.h"
29 #include "gioenumtypes.h"
31 #include "gnetworkingprivate.h"
36 * SECTION:ginetaddress
37 * @short_description: An IPv4/IPv6 address
39 * #GInetAddress represents an IPv4 or IPv6 internet address.
41 * To actually connect to a remote host, you will need a
42 * #GInetSocketAddress (which includes a #GInetAddress as well as a
49 * An IPv4 or IPv6 internet address.
52 /* Networking initialization function, called from inside the g_once of
53 * g_inet_address_get_type()
56 _g_networking_init (void)
60 if (WSAStartup (MAKEWORD (2, 0), &wsadata) != 0)
61 g_error ("Windows Sockets could not be initialized");
65 G_DEFINE_TYPE_WITH_CODE (GInetAddress, g_inet_address, G_TYPE_OBJECT,
66 _g_networking_init ();)
68 struct _GInetAddressPrivate
88 PROP_IS_MC_LINK_LOCAL,
89 PROP_IS_MC_NODE_LOCAL,
91 PROP_IS_MC_SITE_LOCAL,
95 g_inet_address_set_property (GObject *object,
100 GInetAddress *address = G_INET_ADDRESS (object);
105 address->priv->family = g_value_get_enum (value);
109 memcpy (&address->priv->addr, g_value_get_pointer (value),
110 address->priv->family == AF_INET ?
111 sizeof (address->priv->addr.ipv4) :
112 sizeof (address->priv->addr.ipv6));
116 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
123 g_inet_address_get_property (GObject *object,
128 GInetAddress *address = G_INET_ADDRESS (object);
133 g_value_set_enum (value, address->priv->family);
137 g_value_set_pointer (value, &address->priv->addr);
141 g_value_set_boolean (value, g_inet_address_get_is_any (address));
144 case PROP_IS_LOOPBACK:
145 g_value_set_boolean (value, g_inet_address_get_is_loopback (address));
148 case PROP_IS_LINK_LOCAL:
149 g_value_set_boolean (value, g_inet_address_get_is_link_local (address));
152 case PROP_IS_SITE_LOCAL:
153 g_value_set_boolean (value, g_inet_address_get_is_site_local (address));
156 case PROP_IS_MULTICAST:
157 g_value_set_boolean (value, g_inet_address_get_is_multicast (address));
160 case PROP_IS_MC_GLOBAL:
161 g_value_set_boolean (value, g_inet_address_get_is_mc_global (address));
164 case PROP_IS_MC_LINK_LOCAL:
165 g_value_set_boolean (value, g_inet_address_get_is_mc_link_local (address));
168 case PROP_IS_MC_NODE_LOCAL:
169 g_value_set_boolean (value, g_inet_address_get_is_mc_node_local (address));
172 case PROP_IS_MC_ORG_LOCAL:
173 g_value_set_boolean (value, g_inet_address_get_is_mc_org_local (address));
176 case PROP_IS_MC_SITE_LOCAL:
177 g_value_set_boolean (value, g_inet_address_get_is_mc_site_local (address));
181 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
186 g_inet_address_class_init (GInetAddressClass *klass)
188 GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
190 g_type_class_add_private (klass, sizeof (GInetAddressPrivate));
192 gobject_class->set_property = g_inet_address_set_property;
193 gobject_class->get_property = g_inet_address_get_property;
195 g_object_class_install_property (gobject_class, PROP_FAMILY,
196 g_param_spec_enum ("family",
198 _("The address family (IPv4 or IPv6)"),
199 G_TYPE_SOCKET_FAMILY,
200 G_SOCKET_FAMILY_INVALID,
201 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_STATIC_NAME));
203 g_object_class_install_property (gobject_class, PROP_BYTES,
204 g_param_spec_pointer ("bytes",
206 _("The raw address data"),
207 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_STATIC_NAME));
209 g_object_class_install_property (gobject_class, PROP_IS_ANY,
210 g_param_spec_boolean ("is-any",
212 _("See g_inet_address_get_is_any()"),
214 G_PARAM_READABLE | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_STATIC_NAME));
216 g_object_class_install_property (gobject_class, PROP_IS_LINK_LOCAL,
217 g_param_spec_boolean ("is-link-local",
219 _("See g_inet_address_get_is_link_local()"),
221 G_PARAM_READABLE | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_STATIC_NAME));
223 g_object_class_install_property (gobject_class, PROP_IS_LOOPBACK,
224 g_param_spec_boolean ("is-loopback",
226 _("See g_inet_address_get_is_loopback()"),
228 G_PARAM_READABLE | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_STATIC_NAME));
230 g_object_class_install_property (gobject_class, PROP_IS_SITE_LOCAL,
231 g_param_spec_boolean ("is-site-local",
233 _("See g_inet_address_get_is_site_local()"),
235 G_PARAM_READABLE | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_STATIC_NAME));
237 g_object_class_install_property (gobject_class, PROP_IS_MULTICAST,
238 g_param_spec_boolean ("is-multicast",
240 _("See g_inet_address_get_is_multicast()"),
242 G_PARAM_READABLE | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_STATIC_NAME));
244 g_object_class_install_property (gobject_class, PROP_IS_MC_GLOBAL,
245 g_param_spec_boolean ("is-mc-global",
246 _("Is multicast global"),
247 _("See g_inet_address_get_is_mc_global()"),
249 G_PARAM_READABLE | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_STATIC_NAME));
251 g_object_class_install_property (gobject_class, PROP_IS_MC_LINK_LOCAL,
252 g_param_spec_boolean ("is-mc-link-local",
253 _("Is multicast link-local"),
254 _("See g_inet_address_get_is_mc_link_local()"),
256 G_PARAM_READABLE | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_STATIC_NAME));
258 g_object_class_install_property (gobject_class, PROP_IS_MC_NODE_LOCAL,
259 g_param_spec_boolean ("is-mc-node-local",
260 _("Is multicast node-local"),
261 _("See g_inet_address_get_is_mc_node_local()"),
263 G_PARAM_READABLE | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_STATIC_NAME));
265 g_object_class_install_property (gobject_class, PROP_IS_MC_ORG_LOCAL,
266 g_param_spec_boolean ("is-mc-org-local",
267 _("Is multicast org-local"),
268 _("See g_inet_address_get_is_mc_org_local()"),
270 G_PARAM_READABLE | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_STATIC_NAME));
272 g_object_class_install_property (gobject_class, PROP_IS_MC_SITE_LOCAL,
273 g_param_spec_boolean ("is-mc-site-local",
274 _("Is multicast site-local"),
275 _("See g_inet_address_get_is_mc_site_local()"),
277 G_PARAM_READABLE | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_STATIC_NAME));
281 g_inet_address_init (GInetAddress *address)
283 address->priv = G_TYPE_INSTANCE_GET_PRIVATE (address,
285 GInetAddressPrivate);
289 * g_inet_address_new_from_string:
290 * @string: a string representation of an IP address
292 * Parses @string as an IP address and creates a new #GInetAddress.
294 * Returns: a new #GInetAddress corresponding to @string, or %NULL if
295 * @string could not be parsed.
300 g_inet_address_new_from_string (const gchar *string)
303 struct sockaddr_storage sa;
304 struct sockaddr_in *sin = (struct sockaddr_in *)&sa;
305 struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)&sa;
307 #else /* !G_OS_WIN32 */
308 struct in_addr in_addr;
309 struct in6_addr in6_addr;
312 /* Make sure _g_networking_init() has been called */
313 (void) g_inet_address_get_type ();
316 memset (&sa, 0, sizeof (sa));
318 if (WSAStringToAddress ((LPTSTR) string, AF_INET, NULL, (LPSOCKADDR) &sa, &len) == 0)
319 return g_inet_address_new_from_bytes ((guint8 *)&sin->sin_addr, AF_INET);
320 else if (WSAStringToAddress ((LPTSTR) string, AF_INET6, NULL, (LPSOCKADDR) &sa, &len) == 0)
321 return g_inet_address_new_from_bytes ((guint8 *)&sin6->sin6_addr, AF_INET6);
323 #else /* !G_OS_WIN32 */
325 if (inet_pton (AF_INET, string, &in_addr) > 0)
326 return g_inet_address_new_from_bytes ((guint8 *)&in_addr, AF_INET);
327 else if (inet_pton (AF_INET6, string, &in6_addr) > 0)
328 return g_inet_address_new_from_bytes ((guint8 *)&in6_addr, AF_INET6);
334 #define G_INET_ADDRESS_FAMILY_IS_VALID(family) ((family) == AF_INET || (family) == AF_INET6)
337 * g_inet_address_new_from_bytes:
338 * @bytes: raw address data
339 * @family: the address family of @bytes
341 * Creates a new #GInetAddress from the given @family and @bytes.
342 * @bytes should be 4 bytes for %G_INET_ADDRESS_IPV4 and 16 bytes for
343 * %G_INET_ADDRESS_IPV6.
345 * Returns: a new #GInetAddress corresponding to @family and @bytes.
350 g_inet_address_new_from_bytes (const guint8 *bytes,
351 GSocketFamily family)
353 g_return_val_if_fail (G_INET_ADDRESS_FAMILY_IS_VALID (family), NULL);
355 return g_object_new (G_TYPE_INET_ADDRESS,
362 * g_inet_address_new_loopback:
363 * @family: the address family
365 * Creates a #GInetAddress for the loopback address for @family.
367 * Returns: a new #GInetAddress corresponding to the loopback address
373 g_inet_address_new_loopback (GSocketFamily family)
375 g_return_val_if_fail (G_INET_ADDRESS_FAMILY_IS_VALID (family), NULL);
377 if (family == AF_INET)
379 guint8 addr[4] = {127, 0, 0, 1};
381 return g_inet_address_new_from_bytes (addr, family);
384 return g_inet_address_new_from_bytes (in6addr_loopback.s6_addr, family);
388 * g_inet_address_new_any:
389 * @family: the address family
391 * Creates a #GInetAddress for the "any" address (unassigned/"don't
392 * care") for @family.
394 * Returns: a new #GInetAddress corresponding to the "any" address
400 g_inet_address_new_any (GSocketFamily family)
402 g_return_val_if_fail (G_INET_ADDRESS_FAMILY_IS_VALID (family), NULL);
404 if (family == AF_INET)
406 guint8 addr[4] = {0, 0, 0, 0};
408 return g_inet_address_new_from_bytes (addr, family);
411 return g_inet_address_new_from_bytes (in6addr_any.s6_addr, family);
416 * g_inet_address_to_string:
417 * @address: a #GInetAddress
419 * Converts @address to string form.
421 * Returns: a representation of @address as a string, which should be
427 g_inet_address_to_string (GInetAddress *address)
429 gchar buffer[INET6_ADDRSTRLEN];
431 DWORD buflen = sizeof (buffer), addrlen;
432 struct sockaddr_storage sa;
433 struct sockaddr_in *sin = (struct sockaddr_in *)&sa;
434 struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)&sa;
437 g_return_val_if_fail (G_IS_INET_ADDRESS (address), NULL);
440 sa.ss_family = address->priv->family;
441 if (address->priv->family == AF_INET)
443 addrlen = sizeof (*sin);
444 memcpy (&sin->sin_addr, &address->priv->addr.ipv4,
445 sizeof (sin->sin_addr));
450 addrlen = sizeof (*sin6);
451 memcpy (&sin6->sin6_addr, &address->priv->addr.ipv6,
452 sizeof (sin6->sin6_addr));
455 if (WSAAddressToString ((LPSOCKADDR) &sa, addrlen, NULL, buffer, &buflen) != 0)
458 #else /* !G_OS_WIN32 */
460 if (address->priv->family == AF_INET)
461 inet_ntop (AF_INET, &address->priv->addr.ipv4, buffer, sizeof (buffer));
463 inet_ntop (AF_INET6, &address->priv->addr.ipv6, buffer, sizeof (buffer));
466 return g_strdup (buffer);
470 * g_inet_address_to_bytes:
471 * @address: a #GInetAddress
473 * Gets the raw binary address data from @address.
475 * Returns: a pointer to an internal array of the bytes in @address,
476 * which should not be modified, stored, or freed.
481 g_inet_address_to_bytes (GInetAddress *address)
483 g_return_val_if_fail (G_IS_INET_ADDRESS (address), NULL);
485 return (guint8 *)&address->priv->addr;
489 * g_inet_address_get_family:
490 * @address: a #GInetAddress
492 * Gets @address's family
494 * Returns: @address's family
499 g_inet_address_get_family (GInetAddress *address)
501 g_return_val_if_fail (G_IS_INET_ADDRESS (address), FALSE);
503 return address->priv->family;
507 * g_inet_address_get_is_any:
508 * @address: a #GInetAddress
510 * Tests whether @address is the "any" address for its family.
512 * Returns: %TRUE if @address is the "any" address for its family.
517 g_inet_address_get_is_any (GInetAddress *address)
519 g_return_val_if_fail (G_IS_INET_ADDRESS (address), FALSE);
521 if (address->priv->family == AF_INET)
523 guint32 addr4 = g_ntohl (address->priv->addr.ipv4.s_addr);
525 return addr4 == INADDR_ANY;
528 return IN6_IS_ADDR_UNSPECIFIED (&address->priv->addr.ipv6.s6_addr);
532 * g_inet_address_get_is_loopback:
533 * @address: a #GInetAddress
535 * Tests whether @address is the loopback address for its family.
537 * Returns: %TRUE if @address is the loopback address for its family.
542 g_inet_address_get_is_loopback (GInetAddress *address)
544 g_return_val_if_fail (G_IS_INET_ADDRESS (address), FALSE);
546 if (address->priv->family == AF_INET)
548 guint32 addr4 = g_ntohl (address->priv->addr.ipv4.s_addr);
551 return ((addr4 & 0xff000000) == 0x7f000000);
554 return IN6_IS_ADDR_LOOPBACK (&address->priv->addr.ipv6.s6_addr);
558 * g_inet_address_get_is_link_local:
559 * @address: a #GInetAddress
561 * Tests whether @address is a link-local address (that is, if it
562 * identifies a host on a local network that is not connected to the
565 * Returns: %TRUE if @address is a link-local address.
570 g_inet_address_get_is_link_local (GInetAddress *address)
572 g_return_val_if_fail (G_IS_INET_ADDRESS (address), FALSE);
574 if (address->priv->family == AF_INET)
576 guint32 addr4 = g_ntohl (address->priv->addr.ipv4.s_addr);
579 return ((addr4 & 0xffff0000) == 0xa9fe0000);
582 return IN6_IS_ADDR_LINKLOCAL (&address->priv->addr.ipv6.s6_addr);
586 * g_inet_address_get_is_site_local:
587 * @address: a #GInetAddress
589 * Tests whether @address is a site-local address such as 10.0.0.1
590 * (that is, the address identifies a host on a local network that can
591 * not be reached directly from the Internet, but which may have
592 * outgoing Internet connectivity via a NAT or firewall).
594 * Returns: %TRUE if @address is a site-local address.
599 g_inet_address_get_is_site_local (GInetAddress *address)
601 g_return_val_if_fail (G_IS_INET_ADDRESS (address), FALSE);
603 if (address->priv->family == AF_INET)
605 guint32 addr4 = g_ntohl (address->priv->addr.ipv4.s_addr);
607 /* 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16 */
608 return ((addr4 & 0xff000000) == 0x0a000000 ||
609 (addr4 & 0xfff00000) == 0xac100000 ||
610 (addr4 & 0xffff0000) == 0xc0a80000);
613 return IN6_IS_ADDR_SITELOCAL (&address->priv->addr.ipv6.s6_addr);
617 * g_inet_address_get_is_multicast:
618 * @address: a #GInetAddress
620 * Tests whether @address is a multicast address.
622 * Returns: %TRUE if @address is a multicast address.
627 g_inet_address_get_is_multicast (GInetAddress *address)
629 g_return_val_if_fail (G_IS_INET_ADDRESS (address), FALSE);
631 if (address->priv->family == AF_INET)
633 guint32 addr4 = g_ntohl (address->priv->addr.ipv4.s_addr);
635 return IN_MULTICAST (addr4);
638 return IN6_IS_ADDR_MULTICAST (&address->priv->addr.ipv6.s6_addr);
642 * g_inet_address_get_is_mc_global:
643 * @address: a #GInetAddress
645 * Tests whether @address is a global multicast address.
647 * Returns: %TRUE if @address is a global multicast address.
652 g_inet_address_get_is_mc_global (GInetAddress *address)
654 g_return_val_if_fail (G_IS_INET_ADDRESS (address), FALSE);
656 if (address->priv->family == AF_INET)
659 return IN6_IS_ADDR_MC_GLOBAL (&address->priv->addr.ipv6.s6_addr);
663 * g_inet_address_get_is_mc_link_local:
664 * @address: a #GInetAddress
666 * Tests whether @address is a link-local multicast address.
668 * Returns: %TRUE if @address is a link-local multicast address.
673 g_inet_address_get_is_mc_link_local (GInetAddress *address)
675 g_return_val_if_fail (G_IS_INET_ADDRESS (address), FALSE);
677 if (address->priv->family == AF_INET)
680 return IN6_IS_ADDR_MC_LINKLOCAL (&address->priv->addr.ipv6.s6_addr);
684 * g_inet_address_get_is_mc_node_local:
685 * @address: a #GInetAddress
687 * Tests whether @address is a node-local multicast address.
689 * Returns: %TRUE if @address is a node-local multicast address.
694 g_inet_address_get_is_mc_node_local (GInetAddress *address)
696 g_return_val_if_fail (G_IS_INET_ADDRESS (address), FALSE);
698 if (address->priv->family == AF_INET)
701 return IN6_IS_ADDR_MC_NODELOCAL (&address->priv->addr.ipv6.s6_addr);
705 * g_inet_address_get_is_mc_org_local:
706 * @address: a #GInetAddress
708 * Tests whether @address is an organization-local multicast address.
710 * Returns: %TRUE if @address is an organization-local multicast address.
715 g_inet_address_get_is_mc_org_local (GInetAddress *address)
717 g_return_val_if_fail (G_IS_INET_ADDRESS (address), FALSE);
719 if (address->priv->family == AF_INET)
722 return IN6_IS_ADDR_MC_ORGLOCAL (&address->priv->addr.ipv6.s6_addr);
726 * g_inet_address_get_is_mc_site_local:
727 * @address: a #GInetAddress
729 * Tests whether @address is a site-local multicast address.
731 * Returns: %TRUE if @address is a site-local multicast address.
736 g_inet_address_get_is_mc_site_local (GInetAddress *address)
738 g_return_val_if_fail (G_IS_INET_ADDRESS (address), FALSE);
740 if (address->priv->family == AF_INET)
743 return IN6_IS_ADDR_MC_SITELOCAL (&address->priv->addr.ipv6.s6_addr);
746 #define __G_INET_ADDRESS_C__
747 #include "gioaliasdef.c"