| 
									
										
										
										
											2011-10-01 08:31:54 -04:00
										 |  |  | /* GIO - GLib Input, Output and Streaming Library
 | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Copyright 2011 Red Hat, Inc. | 
					
						
							|  |  |  |  * | 
					
						
							| 
									
										
										
										
											2022-05-18 09:12:45 +01:00
										 |  |  |  * SPDX-License-Identifier: LGPL-2.1-or-later | 
					
						
							|  |  |  |  * | 
					
						
							| 
									
										
										
										
											2011-10-01 08:31:54 -04:00
										 |  |  |  * This library is free software; you can redistribute it and/or | 
					
						
							|  |  |  |  * modify it under the terms of the GNU Lesser General Public | 
					
						
							|  |  |  |  * License as published by the Free Software Foundation; either | 
					
						
							| 
									
										
										
										
											2017-05-27 18:21:30 +02:00
										 |  |  |  * version 2.1 of the License, or (at your option) any later version. | 
					
						
							| 
									
										
										
										
											2011-10-01 08:31:54 -04:00
										 |  |  |  * | 
					
						
							|  |  |  |  * This library is distributed in the hope that it will be useful, | 
					
						
							|  |  |  |  * but WITHOUT ANY WARRANTY; without even the implied warranty of | 
					
						
							|  |  |  |  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | 
					
						
							|  |  |  |  * Lesser General Public License for more details. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * You should have received a copy of the GNU Lesser General | 
					
						
							| 
									
										
										
										
											2014-01-23 12:58:29 +01:00
										 |  |  |  * Public License along with this library; if not, see <http://www.gnu.org/licenses/>.
 | 
					
						
							| 
									
										
										
										
											2011-10-01 08:31:54 -04:00
										 |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <config.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <stdlib.h>
 | 
					
						
							|  |  |  | #include <string.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "ginetaddressmask.h"
 | 
					
						
							|  |  |  | #include "ginetaddress.h"
 | 
					
						
							|  |  |  | #include "ginitable.h"
 | 
					
						
							|  |  |  | #include "gioerror.h"
 | 
					
						
							|  |  |  | #include "gioenumtypes.h"
 | 
					
						
							|  |  |  | #include "glibintl.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							| 
									
										
										
										
											2023-10-23 14:38:55 +01:00
										 |  |  |  * GInetAddressMask: | 
					
						
							| 
									
										
										
										
											2011-10-01 08:31:54 -04:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2023-10-23 14:38:55 +01:00
										 |  |  |  * `GInetAddressMask` represents a range of IPv4 or IPv6 addresses | 
					
						
							| 
									
										
										
										
											2011-10-01 08:31:54 -04:00
										 |  |  |  * described by a base address and a length indicating how many bits | 
					
						
							|  |  |  |  * of the base address are relevant for matching purposes. These are | 
					
						
							| 
									
										
										
										
											2023-10-23 14:38:55 +01:00
										 |  |  |  * often given in string form. For example, `10.0.0.0/8`, or `fe80::/10`. | 
					
						
							| 
									
										
										
										
											2011-10-01 08:31:54 -04:00
										 |  |  |  * | 
					
						
							|  |  |  |  * Since: 2.32 | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | struct _GInetAddressMaskPrivate | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   GInetAddress *addr; | 
					
						
							|  |  |  |   guint         length; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-06-11 00:29:58 +01:00
										 |  |  | static void     g_inet_address_mask_initable_iface_init (GInitableIface  *iface); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | G_DEFINE_TYPE_WITH_CODE (GInetAddressMask, g_inet_address_mask, G_TYPE_OBJECT, | 
					
						
							|  |  |  |                          G_ADD_PRIVATE (GInetAddressMask) | 
					
						
							|  |  |  | 			 G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE, | 
					
						
							|  |  |  | 						g_inet_address_mask_initable_iface_init)) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-01 08:31:54 -04:00
										 |  |  | enum | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   PROP_0, | 
					
						
							|  |  |  |   PROP_FAMILY, | 
					
						
							|  |  |  |   PROP_ADDRESS, | 
					
						
							|  |  |  |   PROP_LENGTH | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void | 
					
						
							|  |  |  | g_inet_address_mask_set_property (GObject      *object, | 
					
						
							|  |  |  | 				  guint         prop_id, | 
					
						
							|  |  |  | 				  const GValue *value, | 
					
						
							|  |  |  | 				  GParamSpec   *pspec) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   GInetAddressMask *mask = G_INET_ADDRESS_MASK (object); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   switch (prop_id) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |     case PROP_ADDRESS: | 
					
						
							|  |  |  |       if (mask->priv->addr) | 
					
						
							|  |  |  | 	g_object_unref (mask->priv->addr); | 
					
						
							|  |  |  |       mask->priv->addr = g_value_dup_object (value); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case PROP_LENGTH: | 
					
						
							|  |  |  |       mask->priv->length = g_value_get_uint (value); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     default: | 
					
						
							|  |  |  |       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void | 
					
						
							|  |  |  | g_inet_address_mask_get_property (GObject    *object, | 
					
						
							|  |  |  | 				  guint       prop_id, | 
					
						
							|  |  |  | 				  GValue     *value, | 
					
						
							|  |  |  | 				  GParamSpec *pspec) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   GInetAddressMask *mask = G_INET_ADDRESS_MASK (object); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   switch (prop_id) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |     case PROP_FAMILY: | 
					
						
							|  |  |  |       g_value_set_enum (value, g_inet_address_get_family (mask->priv->addr)); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case PROP_ADDRESS: | 
					
						
							|  |  |  |       g_value_set_object (value, mask->priv->addr); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case PROP_LENGTH: | 
					
						
							|  |  |  |       g_value_set_uint (value, mask->priv->length); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     default: | 
					
						
							|  |  |  |       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-01-01 19:01:14 +01:00
										 |  |  | static void | 
					
						
							|  |  |  | g_inet_address_mask_dispose (GObject *object) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   GInetAddressMask *mask = G_INET_ADDRESS_MASK (object); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   g_clear_object (&mask->priv->addr); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   G_OBJECT_CLASS (g_inet_address_mask_parent_class)->dispose (object); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-01 08:31:54 -04:00
										 |  |  | static void | 
					
						
							|  |  |  | g_inet_address_mask_class_init (GInetAddressMaskClass *klass) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   GObjectClass *gobject_class = G_OBJECT_CLASS (klass); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   gobject_class->set_property = g_inet_address_mask_set_property; | 
					
						
							|  |  |  |   gobject_class->get_property = g_inet_address_mask_get_property; | 
					
						
							| 
									
										
										
										
											2012-01-01 19:01:14 +01:00
										 |  |  |   gobject_class->dispose = g_inet_address_mask_dispose; | 
					
						
							| 
									
										
										
										
											2011-10-01 08:31:54 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-11-29 13:23:09 +00:00
										 |  |  |   /**
 | 
					
						
							|  |  |  |    * GInetAddressMask:family: | 
					
						
							|  |  |  |    * | 
					
						
							|  |  |  |    * The address family (IPv4 or IPv6). | 
					
						
							|  |  |  |    * | 
					
						
							|  |  |  |    * Since: 2.32 | 
					
						
							|  |  |  |    */ | 
					
						
							| 
									
										
										
										
											2011-10-01 08:31:54 -04:00
										 |  |  |   g_object_class_install_property (gobject_class, PROP_FAMILY, | 
					
						
							| 
									
										
										
										
											2023-04-28 01:59:26 +02:00
										 |  |  |                                    g_param_spec_enum ("family", NULL, NULL, | 
					
						
							| 
									
										
										
										
											2011-10-01 08:31:54 -04:00
										 |  |  | 						      G_TYPE_SOCKET_FAMILY, | 
					
						
							|  |  |  | 						      G_SOCKET_FAMILY_INVALID, | 
					
						
							|  |  |  | 						      G_PARAM_READABLE | | 
					
						
							|  |  |  |                                                       G_PARAM_STATIC_STRINGS)); | 
					
						
							| 
									
										
										
										
											2023-11-29 13:23:09 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |   /**
 | 
					
						
							|  |  |  |    * GInetAddressMask:address: | 
					
						
							|  |  |  |    * | 
					
						
							|  |  |  |    * The base address. | 
					
						
							|  |  |  |    * | 
					
						
							|  |  |  |    * Since: 2.32 | 
					
						
							|  |  |  |    */ | 
					
						
							| 
									
										
										
										
											2011-10-01 08:31:54 -04:00
										 |  |  |   g_object_class_install_property (gobject_class, PROP_ADDRESS, | 
					
						
							| 
									
										
										
										
											2023-04-28 01:59:26 +02:00
										 |  |  |                                    g_param_spec_object ("address", NULL, NULL, | 
					
						
							| 
									
										
										
										
											2011-10-01 08:31:54 -04:00
										 |  |  | 							G_TYPE_INET_ADDRESS, | 
					
						
							|  |  |  | 							G_PARAM_READWRITE | | 
					
						
							|  |  |  | 							G_PARAM_STATIC_STRINGS)); | 
					
						
							| 
									
										
										
										
											2023-11-29 13:23:09 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |   /**
 | 
					
						
							|  |  |  |    * GInetAddressMask:length: | 
					
						
							|  |  |  |    * | 
					
						
							|  |  |  |    * The prefix length, in bytes. | 
					
						
							|  |  |  |    * | 
					
						
							|  |  |  |    * Since: 2.32 | 
					
						
							|  |  |  |    */ | 
					
						
							| 
									
										
										
										
											2011-10-01 08:31:54 -04:00
										 |  |  |   g_object_class_install_property (gobject_class, PROP_LENGTH, | 
					
						
							| 
									
										
										
										
											2023-04-28 01:59:26 +02:00
										 |  |  |                                    g_param_spec_uint ("length", NULL, NULL, | 
					
						
							| 
									
										
										
										
											2011-10-01 08:31:54 -04:00
										 |  |  | 						      0, 128, 0, | 
					
						
							|  |  |  | 						      G_PARAM_READWRITE | | 
					
						
							|  |  |  | 						      G_PARAM_STATIC_STRINGS)); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static gboolean | 
					
						
							|  |  |  | g_inet_address_mask_initable_init (GInitable     *initable, | 
					
						
							|  |  |  | 				   GCancellable  *cancellable, | 
					
						
							|  |  |  | 				   GError       **error) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   GInetAddressMask *mask = G_INET_ADDRESS_MASK (initable); | 
					
						
							|  |  |  |   guint addrlen, nbytes, nbits; | 
					
						
							|  |  |  |   const guint8 *bytes; | 
					
						
							|  |  |  |   gboolean ok; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (!mask->priv->addr) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT, | 
					
						
							|  |  |  | 			   _("No address specified")); | 
					
						
							|  |  |  |       return FALSE; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   addrlen = g_inet_address_get_native_size (mask->priv->addr); | 
					
						
							|  |  |  |   if (mask->priv->length > addrlen * 8) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT, | 
					
						
							|  |  |  | 		   _("Length %u is too long for address"), | 
					
						
							|  |  |  | 		   mask->priv->length); | 
					
						
							|  |  |  |       return FALSE; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /* Make sure all the bits after @length are 0 */ | 
					
						
							|  |  |  |   bytes = g_inet_address_to_bytes (mask->priv->addr); | 
					
						
							|  |  |  |   ok = TRUE; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   nbytes = mask->priv->length / 8; | 
					
						
							|  |  |  |   bytes += nbytes; | 
					
						
							|  |  |  |   addrlen -= nbytes; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   nbits = mask->priv->length % 8; | 
					
						
							|  |  |  |   if (nbits) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       if (bytes[0] & (0xFF >> nbits)) | 
					
						
							|  |  |  | 	ok = FALSE; | 
					
						
							|  |  |  |       bytes++; | 
					
						
							|  |  |  |       addrlen--; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   while (addrlen) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       if (bytes[0]) | 
					
						
							|  |  |  | 	ok = FALSE; | 
					
						
							|  |  |  |       bytes++; | 
					
						
							|  |  |  |       addrlen--; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (!ok) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT, | 
					
						
							|  |  |  | 			   _("Address has bits set beyond prefix length")); | 
					
						
							|  |  |  |       return FALSE; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return TRUE; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void | 
					
						
							|  |  |  | g_inet_address_mask_initable_iface_init (GInitableIface  *iface) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   iface->init = g_inet_address_mask_initable_init; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void | 
					
						
							|  |  |  | g_inet_address_mask_init (GInetAddressMask *mask) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2013-06-24 15:43:04 +01:00
										 |  |  |   mask->priv = g_inet_address_mask_get_instance_private (mask); | 
					
						
							| 
									
										
										
										
											2011-10-01 08:31:54 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							|  |  |  |  * g_inet_address_mask_new: | 
					
						
							|  |  |  |  * @addr: a #GInetAddress | 
					
						
							|  |  |  |  * @length: number of bits of @addr to use | 
					
						
							|  |  |  |  * @error: return location for #GError, or %NULL | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Creates a new #GInetAddressMask representing all addresses whose | 
					
						
							|  |  |  |  * first @length bits match @addr. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Returns: a new #GInetAddressMask, or %NULL on error | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Since: 2.32 | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | GInetAddressMask * | 
					
						
							|  |  |  | g_inet_address_mask_new (GInetAddress  *addr, | 
					
						
							|  |  |  | 			 guint          length, | 
					
						
							|  |  |  | 			 GError       **error) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   return g_initable_new (G_TYPE_INET_ADDRESS_MASK, NULL, error, | 
					
						
							|  |  |  | 			 "address", addr, | 
					
						
							|  |  |  | 			 "length", length, | 
					
						
							|  |  |  | 			 NULL); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							|  |  |  |  * g_inet_address_mask_new_from_string: | 
					
						
							|  |  |  |  * @mask_string: an IP address or address/length string | 
					
						
							|  |  |  |  * @error: return location for #GError, or %NULL | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Parses @mask_string as an IP address and (optional) length, and | 
					
						
							|  |  |  |  * creates a new #GInetAddressMask. The length, if present, is | 
					
						
							|  |  |  |  * delimited by a "/". If it is not present, then the length is | 
					
						
							|  |  |  |  * assumed to be the full length of the address. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Returns: a new #GInetAddressMask corresponding to @string, or %NULL | 
					
						
							|  |  |  |  * on error. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Since: 2.32 | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | GInetAddressMask * | 
					
						
							|  |  |  | g_inet_address_mask_new_from_string (const gchar  *mask_string, | 
					
						
							|  |  |  | 				     GError      **error) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   GInetAddressMask *mask; | 
					
						
							|  |  |  |   GInetAddress *addr; | 
					
						
							|  |  |  |   gchar *slash; | 
					
						
							|  |  |  |   guint length; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   slash = strchr (mask_string, '/'); | 
					
						
							|  |  |  |   if (slash) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       gchar *address, *end; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       length = strtoul (slash + 1, &end, 10); | 
					
						
							|  |  |  |       if (*end || !*(slash + 1)) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 	parse_error: | 
					
						
							|  |  |  | 	  g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT, | 
					
						
							| 
									
										
										
										
											2016-09-30 05:47:15 +02:00
										 |  |  | 		       _("Could not parse “%s” as IP address mask"), | 
					
						
							| 
									
										
										
										
											2011-10-01 08:31:54 -04:00
										 |  |  | 		       mask_string); | 
					
						
							|  |  |  | 	  return NULL; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       address = g_strndup (mask_string, slash - mask_string); | 
					
						
							|  |  |  |       addr = g_inet_address_new_from_string (address); | 
					
						
							|  |  |  |       g_free (address); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       if (!addr) | 
					
						
							|  |  |  | 	goto parse_error; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   else | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       addr = g_inet_address_new_from_string (mask_string); | 
					
						
							|  |  |  |       if (!addr) | 
					
						
							|  |  |  | 	goto parse_error; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       length = g_inet_address_get_native_size (addr) * 8; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   mask = g_inet_address_mask_new (addr, length, error); | 
					
						
							|  |  |  |   g_object_unref (addr); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return mask; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							|  |  |  |  * g_inet_address_mask_to_string: | 
					
						
							|  |  |  |  * @mask: a #GInetAddressMask | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Converts @mask back to its corresponding string form. | 
					
						
							|  |  |  |  * | 
					
						
							| 
									
										
										
										
											2014-02-19 19:35:23 -05:00
										 |  |  |  * Returns: a string corresponding to @mask. | 
					
						
							| 
									
										
										
										
											2011-10-01 08:31:54 -04:00
										 |  |  |  * | 
					
						
							|  |  |  |  * Since: 2.32 | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | gchar * | 
					
						
							|  |  |  | g_inet_address_mask_to_string (GInetAddressMask *mask) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   gchar *addr_string, *mask_string; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   g_return_val_if_fail (G_IS_INET_ADDRESS_MASK (mask), NULL); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   addr_string = g_inet_address_to_string (mask->priv->addr); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (mask->priv->length == (g_inet_address_get_native_size (mask->priv->addr) * 8)) | 
					
						
							|  |  |  |     return addr_string; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   mask_string = g_strdup_printf ("%s/%u", addr_string, mask->priv->length); | 
					
						
							|  |  |  |   g_free (addr_string); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return mask_string; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							|  |  |  |  * g_inet_address_mask_get_family: | 
					
						
							|  |  |  |  * @mask: a #GInetAddressMask | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Gets the #GSocketFamily of @mask's address | 
					
						
							|  |  |  |  * | 
					
						
							| 
									
										
										
										
											2014-02-19 19:35:23 -05:00
										 |  |  |  * Returns: the #GSocketFamily of @mask's address | 
					
						
							| 
									
										
										
										
											2011-10-01 08:31:54 -04:00
										 |  |  |  * | 
					
						
							|  |  |  |  * Since: 2.32 | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | GSocketFamily | 
					
						
							|  |  |  | g_inet_address_mask_get_family (GInetAddressMask *mask) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   g_return_val_if_fail (G_IS_INET_ADDRESS_MASK (mask), G_SOCKET_FAMILY_INVALID); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return g_inet_address_get_family (mask->priv->addr); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							|  |  |  |  * g_inet_address_mask_get_address: | 
					
						
							|  |  |  |  * @mask: a #GInetAddressMask | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Gets @mask's base address | 
					
						
							|  |  |  |  * | 
					
						
							| 
									
										
										
										
											2014-02-19 19:35:23 -05:00
										 |  |  |  * Returns: (transfer none): @mask's base address | 
					
						
							| 
									
										
										
										
											2011-10-01 08:31:54 -04:00
										 |  |  |  * | 
					
						
							|  |  |  |  * Since: 2.32 | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | GInetAddress * | 
					
						
							|  |  |  | g_inet_address_mask_get_address (GInetAddressMask *mask) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   g_return_val_if_fail (G_IS_INET_ADDRESS_MASK (mask), NULL); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return mask->priv->addr; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							|  |  |  |  * g_inet_address_mask_get_length: | 
					
						
							|  |  |  |  * @mask: a #GInetAddressMask | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Gets @mask's length | 
					
						
							|  |  |  |  * | 
					
						
							| 
									
										
										
										
											2014-02-19 19:35:23 -05:00
										 |  |  |  * Returns: @mask's length | 
					
						
							| 
									
										
										
										
											2011-10-01 08:31:54 -04:00
										 |  |  |  * | 
					
						
							|  |  |  |  * Since: 2.32 | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | guint | 
					
						
							|  |  |  | g_inet_address_mask_get_length (GInetAddressMask *mask) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   g_return_val_if_fail (G_IS_INET_ADDRESS_MASK (mask), 0); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return mask->priv->length; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							|  |  |  |  * g_inet_address_mask_matches: | 
					
						
							|  |  |  |  * @mask: a #GInetAddressMask | 
					
						
							|  |  |  |  * @address: a #GInetAddress | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Tests if @address falls within the range described by @mask. | 
					
						
							|  |  |  |  * | 
					
						
							| 
									
										
										
										
											2014-02-19 19:35:23 -05:00
										 |  |  |  * Returns: whether @address falls within the range described by | 
					
						
							| 
									
										
										
										
											2011-10-01 08:31:54 -04:00
										 |  |  |  * @mask. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Since: 2.32 | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | gboolean | 
					
						
							|  |  |  | g_inet_address_mask_matches (GInetAddressMask *mask, | 
					
						
							|  |  |  | 			     GInetAddress     *address) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   const guint8 *maskbytes, *addrbytes; | 
					
						
							|  |  |  |   int nbytes, nbits; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   g_return_val_if_fail (G_IS_INET_ADDRESS_MASK (mask), FALSE); | 
					
						
							|  |  |  |   g_return_val_if_fail (G_IS_INET_ADDRESS (address), FALSE); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (g_inet_address_get_family (mask->priv->addr) != | 
					
						
							|  |  |  |       g_inet_address_get_family (address)) | 
					
						
							|  |  |  |     return FALSE; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (mask->priv->length == 0) | 
					
						
							|  |  |  |     return TRUE; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   maskbytes = g_inet_address_to_bytes (mask->priv->addr); | 
					
						
							|  |  |  |   addrbytes = g_inet_address_to_bytes (address); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   nbytes = mask->priv->length / 8; | 
					
						
							|  |  |  |   if (nbytes != 0 && memcmp (maskbytes, addrbytes, nbytes) != 0) | 
					
						
							|  |  |  |     return FALSE; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   nbits = mask->priv->length % 8; | 
					
						
							|  |  |  |   if (nbits == 0) | 
					
						
							|  |  |  |     return TRUE; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return maskbytes[nbytes] == (addrbytes[nbytes] & (0xFF << (8 - nbits))); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							|  |  |  |  * g_inet_address_mask_equal: | 
					
						
							|  |  |  |  * @mask: a #GInetAddressMask | 
					
						
							|  |  |  |  * @mask2: another #GInetAddressMask | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Tests if @mask and @mask2 are the same mask. | 
					
						
							|  |  |  |  * | 
					
						
							| 
									
										
										
										
											2014-02-19 19:35:23 -05:00
										 |  |  |  * Returns: whether @mask and @mask2 are the same mask | 
					
						
							| 
									
										
										
										
											2011-10-01 08:31:54 -04:00
										 |  |  |  * | 
					
						
							|  |  |  |  * Since: 2.32 | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | gboolean | 
					
						
							|  |  |  | g_inet_address_mask_equal (GInetAddressMask  *mask, | 
					
						
							|  |  |  | 			   GInetAddressMask  *mask2) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2014-07-17 18:37:04 +02:00
										 |  |  |   g_return_val_if_fail (G_IS_INET_ADDRESS_MASK (mask), FALSE); | 
					
						
							|  |  |  |   g_return_val_if_fail (G_IS_INET_ADDRESS_MASK (mask2), FALSE); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-01 08:31:54 -04:00
										 |  |  |   return ((mask->priv->length == mask2->priv->length) && | 
					
						
							|  |  |  | 	  g_inet_address_equal (mask->priv->addr, mask2->priv->addr)); | 
					
						
							|  |  |  | } |