diff options
Diffstat (limited to 'common/gdm-address.c')
-rw-r--r-- | common/gdm-address.c | 448 |
1 files changed, 0 insertions, 448 deletions
diff --git a/common/gdm-address.c b/common/gdm-address.c deleted file mode 100644 index ec488b23..00000000 --- a/common/gdm-address.c +++ /dev/null @@ -1,448 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- - * - * Copyright (C) 2007 William Jon McCann <mccann@jhu.edu> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - */ - - -#include "config.h" - -#include <stdlib.h> -#include <stdio.h> -#include <fcntl.h> -#include <unistd.h> -#include <string.h> -#ifdef HAS_SYS_SOCKET -#include <sys/socket.h> -#endif -#include <netdb.h> - -#ifndef G_OS_WIN32 -#include <sys/socket.h> -#include <sys/select.h> -#include <netinet/in.h> -#include <arpa/inet.h> -#else -#include <winsock2.h> -#include <ws2tcpip.h> -#endif - -#include <glib-object.h> - -#include "gdm-address.h" - -struct _GdmAddress -{ - struct sockaddr_storage *ss; -}; - -/* Register GdmAddress in the glib type system */ -GType -gdm_address_get_type (void) -{ - static GType addr_type = 0; - - if (addr_type == 0) { - addr_type = g_boxed_type_register_static ("GdmAddress", - (GBoxedCopyFunc) gdm_address_copy, - (GBoxedFreeFunc) gdm_address_free); - } - - return addr_type; -} - -/** - * gdm_address_get_family_type: - * @address: A pointer to a #GdmAddress - * - * Use this function to retrive the address family of @address. - * - * Return value: The address family of @address. - **/ -int -gdm_address_get_family_type (GdmAddress *address) -{ - g_return_val_if_fail (address != NULL, -1); - - return address->ss->ss_family; -} - - -/** - * gdm_address_new_from_sockaddr: - * @sa: A pointer to a sockaddr. - * @size: size of sockaddr in bytes. - * - * Creates a new #GdmAddress from @sa. - * - * Return value: The new #GdmAddress - * or %NULL if @sa was invalid or the address family isn't supported. - **/ -GdmAddress * -gdm_address_new_from_sockaddr (struct sockaddr *sa, - size_t size) -{ - GdmAddress *addr; - - g_return_val_if_fail (sa != NULL, NULL); - g_return_val_if_fail (size >= sizeof (struct sockaddr), NULL); - g_return_val_if_fail (size <= sizeof (struct sockaddr_storage), NULL); - - addr = g_new0 (GdmAddress, 1); - addr->ss = g_new0 (struct sockaddr_storage, 1); - memcpy (addr->ss, sa, size); - - return addr; -} - -/** - * gdm_address_get_sockaddr_storage: - * @address: A #GdmAddress - * - * This function tanslates @address into a equivalent - * sockaddr_storage - * - * Return value: A newly allocated sockaddr_storage structure the caller must free - * or %NULL if @address did not point to a valid #GdmAddress. - **/ -struct sockaddr_storage * -gdm_address_get_sockaddr_storage (GdmAddress *address) -{ - struct sockaddr_storage *ss; - - g_return_val_if_fail (address != NULL, NULL); - - ss = g_memdup (address->ss, sizeof (struct sockaddr_storage)); - - return ss; -} - -struct sockaddr_storage * -gdm_address_peek_sockaddr_storage (GdmAddress *address) -{ - g_return_val_if_fail (address != NULL, NULL); - - return address->ss; -} - -static gboolean -v4_v4_equal (const struct sockaddr_in *a, - const struct sockaddr_in *b) -{ - return a->sin_addr.s_addr == b->sin_addr.s_addr; -} - -#ifdef ENABLE_IPV6 -static gboolean -v6_v6_equal (struct sockaddr_in6 *a, - struct sockaddr_in6 *b) -{ - return IN6_ARE_ADDR_EQUAL (&a->sin6_addr, &b->sin6_addr); -} -#endif - -#define SA(__s) ((struct sockaddr *) __s) -#define SIN(__s) ((struct sockaddr_in *) __s) -#define SIN6(__s) ((struct sockaddr_in6 *) __s) - -gboolean -gdm_address_equal (GdmAddress *a, - GdmAddress *b) -{ - guint8 fam_a; - guint8 fam_b; - - g_return_val_if_fail (a != NULL || a->ss != NULL, FALSE); - g_return_val_if_fail (b != NULL || 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; -} - -gboolean -gdm_address_get_hostname (GdmAddress *address, - char **hostnamep) -{ - char host [NI_MAXHOST]; - int res; - gboolean ret; - - g_return_val_if_fail (address != NULL || address->ss != NULL, FALSE); - - ret = FALSE; - - host [0] = '\0'; - res = getnameinfo ((const struct sockaddr *)address->ss, - sizeof (struct sockaddr_storage), - host, sizeof (host), - NULL, 0, - 0); - if (res == 0) { - ret = TRUE; - goto done; - } else { - g_warning ("Unable lookup hostname: %s", gai_strerror (res)); - gdm_address_debug (address); - } - - /* try numeric? */ - - done: - if (hostnamep != NULL) { - *hostnamep = g_strdup (host); - } - - return ret; -} - -gboolean -gdm_address_get_numeric_info (GdmAddress *address, - char **hostp, - char **servp) -{ - char host [NI_MAXHOST]; - char serv [NI_MAXSERV]; - int res; - gboolean ret; - - g_return_val_if_fail (address != NULL || address->ss != NULL, FALSE); - - ret = FALSE; - - host [0] = '\0'; - serv [0] = '\0'; - res = getnameinfo ((const struct sockaddr *)address->ss, - sizeof (struct sockaddr_storage), - host, sizeof (host), - serv, sizeof (serv), - NI_NUMERICHOST | NI_NUMERICSERV); - if (res != 0) { - g_warning ("Unable lookup numeric info: %s", gai_strerror (res)); - } else { - ret = TRUE; - } - - if (servp != NULL) { - *servp = g_strdup (serv); - } - if (hostp != NULL) { - *hostp = g_strdup (host); - } - - return ret; -} - -gboolean -gdm_address_is_loopback (GdmAddress *address) -{ - g_return_val_if_fail (address != NULL || address->ss != NULL, FALSE); - - switch (address->ss->ss_family){ -#ifdef AF_INET6 - case AF_INET6: - return IN6_IS_ADDR_LOOPBACK (&((struct sockaddr_in6 *)address->ss)->sin6_addr); - break; -#endif - case AF_INET: - return (INADDR_LOOPBACK == htonl (((struct sockaddr_in *)address->ss)->sin_addr.s_addr)); - break; - default: - break; - } - - return FALSE; -} - -const GList * -gdm_address_peek_local_list (void) -{ - static GList *the_list = NULL; - static time_t last_time = 0; - char hostbuf[BUFSIZ]; - struct addrinfo hints; - struct addrinfo *result; - struct addrinfo *res; - - /* Don't check more then every 5 seconds */ - if (last_time + 5 > time (NULL)) { - return the_list; - } - - g_list_foreach (the_list, (GFunc)gdm_address_free, NULL); - g_list_free (the_list); - the_list = NULL; - - last_time = time (NULL); - - hostbuf[BUFSIZ-1] = '\0'; - if (gethostname (hostbuf, BUFSIZ-1) != 0) { - g_debug ("%s: Could not get server hostname, using localhost", "gdm_peek_local_address_list"); - snprintf (hostbuf, BUFSIZ-1, "localhost"); - } - - memset (&hints, 0, sizeof (hints)); - hints.ai_family = AF_INET; -#ifdef ENABLE_IPV6 - hints.ai_family |= AF_INET6; -#endif - - result = NULL; - if (getaddrinfo (hostbuf, NULL, &hints, &result) != 0) { - g_debug ("%s: Could not get address from hostname!", "gdm_peek_local_address_list"); - - return NULL; - } - - for (res = result; res != NULL; res = res->ai_next) { - GdmAddress *address; - - address = gdm_address_new_from_sockaddr (res->ai_addr, res->ai_addrlen); - the_list = g_list_append (the_list, address); - } - - if (result != NULL) { - freeaddrinfo (result); - result = NULL; - } - - return the_list; -} - -gboolean -gdm_address_is_local (GdmAddress *address) -{ - const GList *list; - - if (gdm_address_is_loopback (address)) { - return TRUE; - } - - list = gdm_address_peek_local_list (); - - while (list != NULL) { - GdmAddress *addr = list->data; - - if (gdm_address_equal (address, addr)) { - return TRUE; - } - - list = list->next; - } - - return FALSE; -} - -/** - * gdm_address_copy: - * @address: A #GdmAddress. - * - * Duplicates @address. - * - * Return value: Duplicated @address or %NULL if @address was not valid. - **/ -GdmAddress * -gdm_address_copy (GdmAddress *address) -{ - GdmAddress *addr; - - g_return_val_if_fail (address != NULL, NULL); - - addr = g_new0 (GdmAddress, 1); - addr->ss = g_memdup (address->ss, sizeof (struct sockaddr_storage)); - - return addr; -} - -/** - * gdm_address_free: - * @address: A #GdmAddress. - * - * Frees the memory allocated for @address. - **/ -void -gdm_address_free (GdmAddress *address) -{ - g_return_if_fail (address != NULL); - - g_free (address->ss); - g_free (address); -} - -/* for debugging */ -static const char * -address_family_str (GdmAddress *address) -{ - const char *str; - switch (address->ss->ss_family) { - case AF_INET: - str = "inet"; - break; - case AF_INET6: - str = "inet6"; - break; - case AF_UNIX: - str = "unix"; - break; - case AF_UNSPEC: - str = "unspecified"; - break; - default: - str = "unknown"; - break; - } - return str; -} - -void -gdm_address_debug (GdmAddress *address) -{ - char *hostname; - char *host; - char *port; - - g_return_if_fail (address != NULL); - - hostname = NULL; - host = NULL; - port = NULL; - - gdm_address_get_hostname (address, &hostname); - gdm_address_get_numeric_info (address, &host, &port); - - g_debug ("Address family:%d (%s) hostname:%s host:%s port:%s local:%d loopback:%d", - address->ss->ss_family, - address_family_str (address), - hostname, - host, - port, - gdm_address_is_local (address), - gdm_address_is_loopback (address)); - - g_free (hostname); - g_free (host); - g_free (port); -} |