gboolean gdm_address_equal (GdmAddress *a, GdmAddress *b) { guint8 fam_a; guint8 fam_b; g_return_val_if_fail (a != NULL, FALSE); g_return_val_if_fail (a->ss != NULL, FALSE); g_return_val_if_fail (b != NULL, FALSE); g_return_val_if_fail (b->ss != NULL, FALSE); fam_a = a->ss->ss_family; fam_b = b->ss->ss_family; if (fam_a == AF_INET && fam_b == AF_INET) { return v4_v4_equal (SIN (a->ss), SIN (b->ss)); } #ifdef ENABLE_IPV6 else if (fam_a == AF_INET6 && fam_b == AF_INET6) { return v6_v6_equal (SIN6 (a->ss), SIN6 (b->ss)); } #endif return FALSE; }
static gboolean v4_v6_match (const struct sockaddr_in *a4, const struct sockaddr_in6 *b6, guint prefix) { struct sockaddr_in b4; guint32 v4_numeric; if (! IN6_IS_ADDR_V4MAPPED (&b6->sin6_addr)) { return FALSE; } memset (&b4, 0, sizeof (b4)); v4_numeric = b6->sin6_addr.s6_addr[12] << 24 | b6->sin6_addr.s6_addr[13] << 16 | b6->sin6_addr.s6_addr[14] << 8 | b6->sin6_addr.s6_addr[15]; b4.sin_addr.s_addr = g_htonl (v4_numeric); if (prefix == 0 || prefix > 31) { return v4_v4_equal (a4, &b4); } return v4_v4_match (a4, &b4, prefix); }
/** * gnome_vfs_address_match: * @a: A #GnomeVFSAddress * @b: A #GnomeVFSAddress to compare with @a * @prefix: Number of bits to take into account starting * from the left most one. * * Matches the first @prefix number of bits of two given #GnomeVFSAddress * objects and returns TRUE of they match otherwise FALSE. This function can * also match mapped address (i.e. IPv4 mapped IPv6 addresses). * * Return value: TRUE if the two addresses match. * * Since: 2.14 **/ gboolean gnome_vfs_address_match (const GnomeVFSAddress *a, const GnomeVFSAddress *b, guint prefix) { guint8 fam_a; guint8 fam_b; g_return_val_if_fail (a != NULL || a->sa != NULL, FALSE); g_return_val_if_fail (b != NULL || b->sa != NULL, FALSE); fam_a = a->sa->sa_family; fam_b = b->sa->sa_family; if (fam_a == AF_INET && fam_b == AF_INET) { if (prefix == 0 || prefix > 31) { return v4_v4_equal (SIN (a->sa), SIN (b->sa)); } else { return v4_v4_match (SIN (a->sa), SIN (b->sa), prefix); } } #ifdef ENABLE_IPV6 else if (fam_a == AF_INET6 && fam_b == AF_INET6) { if (prefix == 0 || prefix > 127) { return v6_v6_equal (SIN6 (a->sa), SIN6 (b->sa)); } else { return v6_v6_match (SIN6 (a->sa), SIN6 (b->sa), prefix); } } else if (fam_a == AF_INET && fam_b == AF_INET6) { return v4_v6_match (SIN (a->sa), SIN6 (b->sa), prefix); } else if (fam_a == AF_INET6 && fam_b == AF_INET) { return v4_v6_match (SIN (b->sa), SIN6 (a->sa), prefix); } #endif /* This is the case when we are trying to compare unkown family types */ g_assert_not_reached (); return FALSE; }
/** * gnome_vfs_address_equal: * @a: A #GnomeVFSAddress * @b: A #GnomeVFSAddress to compare with @a * * Compares two #GnomeVFSAddress objects and returns TRUE if they have the * addresses are equal as well as the address family type. * * Return value: TRUE if the two addresses match. * * Since: 2.14 **/ gboolean gnome_vfs_address_equal (const GnomeVFSAddress *a, const GnomeVFSAddress *b) { guint8 fam_a; guint8 fam_b; g_return_val_if_fail (a != NULL || a->sa != NULL, FALSE); g_return_val_if_fail (b != NULL || b->sa != NULL, FALSE); fam_a = a->sa->sa_family; fam_b = b->sa->sa_family; if (fam_a == AF_INET && fam_b == AF_INET) { return v4_v4_equal (SIN (a->sa), SIN (b->sa)); } #ifdef ENABLE_IPV6 else if (fam_a == AF_INET6 && fam_b == AF_INET6) { return v6_v6_equal (SIN6 (a->sa), SIN6 (b->sa)); } #endif return FALSE; }