355b4669e025ff377602b6fc7caaf30dbc218371jacobs/*
355b4669e025ff377602b6fc7caaf30dbc218371jacobs * "$Id: http-addr.c 148 2006-04-25 16:54:17Z njacobs $"
355b4669e025ff377602b6fc7caaf30dbc218371jacobs *
355b4669e025ff377602b6fc7caaf30dbc218371jacobs * HTTP address routines for the Common UNIX Printing System (CUPS).
355b4669e025ff377602b6fc7caaf30dbc218371jacobs *
355b4669e025ff377602b6fc7caaf30dbc218371jacobs * Copyright 1997-2005 by Easy Software Products, all rights reserved.
355b4669e025ff377602b6fc7caaf30dbc218371jacobs *
355b4669e025ff377602b6fc7caaf30dbc218371jacobs * These coded instructions, statements, and computer programs are the
355b4669e025ff377602b6fc7caaf30dbc218371jacobs * property of Easy Software Products and are protected by Federal
355b4669e025ff377602b6fc7caaf30dbc218371jacobs * copyright law. Distribution and use rights are outlined in the file
355b4669e025ff377602b6fc7caaf30dbc218371jacobs * "LICENSE.txt" which should have been included with this file. If this
355b4669e025ff377602b6fc7caaf30dbc218371jacobs * file is missing or damaged please contact Easy Software Products
355b4669e025ff377602b6fc7caaf30dbc218371jacobs * at:
355b4669e025ff377602b6fc7caaf30dbc218371jacobs *
355b4669e025ff377602b6fc7caaf30dbc218371jacobs * Attn: CUPS Licensing Information
355b4669e025ff377602b6fc7caaf30dbc218371jacobs * Easy Software Products
355b4669e025ff377602b6fc7caaf30dbc218371jacobs * 44141 Airport View Drive, Suite 204
355b4669e025ff377602b6fc7caaf30dbc218371jacobs * Hollywood, Maryland 20636 USA
355b4669e025ff377602b6fc7caaf30dbc218371jacobs *
355b4669e025ff377602b6fc7caaf30dbc218371jacobs * Voice: (301) 373-9600
355b4669e025ff377602b6fc7caaf30dbc218371jacobs * EMail: cups-info@cups.org
355b4669e025ff377602b6fc7caaf30dbc218371jacobs * WWW: http://www.cups.org
355b4669e025ff377602b6fc7caaf30dbc218371jacobs *
355b4669e025ff377602b6fc7caaf30dbc218371jacobs * Contents:
355b4669e025ff377602b6fc7caaf30dbc218371jacobs *
355b4669e025ff377602b6fc7caaf30dbc218371jacobs * httpAddrAny() - Check for the "any" address.
355b4669e025ff377602b6fc7caaf30dbc218371jacobs * httpAddrEqual() - Compare two addresses.
355b4669e025ff377602b6fc7caaf30dbc218371jacobs * httpAddrLoad() - Load a host entry address into an HTTP address.
355b4669e025ff377602b6fc7caaf30dbc218371jacobs * httpAddrLocalhost() - Check for the local loopback address.
355b4669e025ff377602b6fc7caaf30dbc218371jacobs * httpAddrLookup() - Lookup the hostname associated with the address.
355b4669e025ff377602b6fc7caaf30dbc218371jacobs * httpAddrString() - Convert an IP address to a dotted string.
355b4669e025ff377602b6fc7caaf30dbc218371jacobs * httpGetHostByName() - Lookup a hostname or IP address, and return
355b4669e025ff377602b6fc7caaf30dbc218371jacobs * address records for the specified name.
355b4669e025ff377602b6fc7caaf30dbc218371jacobs */
355b4669e025ff377602b6fc7caaf30dbc218371jacobs
355b4669e025ff377602b6fc7caaf30dbc218371jacobs/*
355b4669e025ff377602b6fc7caaf30dbc218371jacobs * Include necessary headers...
355b4669e025ff377602b6fc7caaf30dbc218371jacobs */
355b4669e025ff377602b6fc7caaf30dbc218371jacobs
355b4669e025ff377602b6fc7caaf30dbc218371jacobs#pragma ident "%Z%%M% %I% %E% SMI"
355b4669e025ff377602b6fc7caaf30dbc218371jacobs
355b4669e025ff377602b6fc7caaf30dbc218371jacobs#include "http.h"
355b4669e025ff377602b6fc7caaf30dbc218371jacobs#include "debug.h"
355b4669e025ff377602b6fc7caaf30dbc218371jacobs#include "string.h"
355b4669e025ff377602b6fc7caaf30dbc218371jacobs#include <ctype.h>
355b4669e025ff377602b6fc7caaf30dbc218371jacobs
355b4669e025ff377602b6fc7caaf30dbc218371jacobs
355b4669e025ff377602b6fc7caaf30dbc218371jacobs/*
355b4669e025ff377602b6fc7caaf30dbc218371jacobs * 'httpAddrAny()' - Check for the "any" address.
355b4669e025ff377602b6fc7caaf30dbc218371jacobs */
355b4669e025ff377602b6fc7caaf30dbc218371jacobs
355b4669e025ff377602b6fc7caaf30dbc218371jacobsint /* O - 1 if "any", 0 otherwise */
355b4669e025ff377602b6fc7caaf30dbc218371jacobshttpAddrAny(const http_addr_t *addr) /* I - Address to check */
355b4669e025ff377602b6fc7caaf30dbc218371jacobs{
355b4669e025ff377602b6fc7caaf30dbc218371jacobs#ifdef AF_INET6
355b4669e025ff377602b6fc7caaf30dbc218371jacobs if (addr->addr.sa_family == AF_INET6 &&
355b4669e025ff377602b6fc7caaf30dbc218371jacobs IN6_IS_ADDR_UNSPECIFIED(&(addr->ipv6.sin6_addr)))
355b4669e025ff377602b6fc7caaf30dbc218371jacobs return (1);
355b4669e025ff377602b6fc7caaf30dbc218371jacobs#endif /* AF_INET6 */
355b4669e025ff377602b6fc7caaf30dbc218371jacobs
355b4669e025ff377602b6fc7caaf30dbc218371jacobs if (addr->addr.sa_family == AF_INET &&
355b4669e025ff377602b6fc7caaf30dbc218371jacobs ntohl(addr->ipv4.sin_addr.s_addr) == 0x00000000)
355b4669e025ff377602b6fc7caaf30dbc218371jacobs return (1);
355b4669e025ff377602b6fc7caaf30dbc218371jacobs
355b4669e025ff377602b6fc7caaf30dbc218371jacobs return (0);
355b4669e025ff377602b6fc7caaf30dbc218371jacobs}
355b4669e025ff377602b6fc7caaf30dbc218371jacobs
355b4669e025ff377602b6fc7caaf30dbc218371jacobs
355b4669e025ff377602b6fc7caaf30dbc218371jacobs/*
355b4669e025ff377602b6fc7caaf30dbc218371jacobs * 'httpAddrEqual()' - Compare two addresses.
355b4669e025ff377602b6fc7caaf30dbc218371jacobs */
355b4669e025ff377602b6fc7caaf30dbc218371jacobs
355b4669e025ff377602b6fc7caaf30dbc218371jacobsint /* O - 1 if equal, 0 if != */
355b4669e025ff377602b6fc7caaf30dbc218371jacobshttpAddrEqual(const http_addr_t *addr1, /* I - First address */
355b4669e025ff377602b6fc7caaf30dbc218371jacobs const http_addr_t *addr2) /* I - Second address */
355b4669e025ff377602b6fc7caaf30dbc218371jacobs{
355b4669e025ff377602b6fc7caaf30dbc218371jacobs if (addr1->addr.sa_family != addr2->addr.sa_family)
355b4669e025ff377602b6fc7caaf30dbc218371jacobs return (0);
355b4669e025ff377602b6fc7caaf30dbc218371jacobs
355b4669e025ff377602b6fc7caaf30dbc218371jacobs#ifdef AF_INET6
355b4669e025ff377602b6fc7caaf30dbc218371jacobs if (addr1->addr.sa_family == AF_INET6)
355b4669e025ff377602b6fc7caaf30dbc218371jacobs return (memcmp(&(addr1->ipv6.sin6_addr), &(addr2->ipv6.sin6_addr), 16) == 0);
355b4669e025ff377602b6fc7caaf30dbc218371jacobs#endif /* AF_INET6 */
355b4669e025ff377602b6fc7caaf30dbc218371jacobs
355b4669e025ff377602b6fc7caaf30dbc218371jacobs return (addr1->ipv4.sin_addr.s_addr == addr2->ipv4.sin_addr.s_addr);
355b4669e025ff377602b6fc7caaf30dbc218371jacobs}
355b4669e025ff377602b6fc7caaf30dbc218371jacobs
355b4669e025ff377602b6fc7caaf30dbc218371jacobs
355b4669e025ff377602b6fc7caaf30dbc218371jacobs/*
355b4669e025ff377602b6fc7caaf30dbc218371jacobs * 'httpAddrLoad()' - Load a host entry address into an HTTP address.
355b4669e025ff377602b6fc7caaf30dbc218371jacobs */
355b4669e025ff377602b6fc7caaf30dbc218371jacobs
355b4669e025ff377602b6fc7caaf30dbc218371jacobsvoid
355b4669e025ff377602b6fc7caaf30dbc218371jacobshttpAddrLoad(const struct hostent *host, /* I - Host entry */
355b4669e025ff377602b6fc7caaf30dbc218371jacobs int port, /* I - Port number */
355b4669e025ff377602b6fc7caaf30dbc218371jacobs int n, /* I - Index into host entry */
355b4669e025ff377602b6fc7caaf30dbc218371jacobs http_addr_t *addr) /* O - Address to load */
355b4669e025ff377602b6fc7caaf30dbc218371jacobs{
355b4669e025ff377602b6fc7caaf30dbc218371jacobs#ifdef AF_INET6
355b4669e025ff377602b6fc7caaf30dbc218371jacobs if (host->h_addrtype == AF_INET6)
355b4669e025ff377602b6fc7caaf30dbc218371jacobs {
355b4669e025ff377602b6fc7caaf30dbc218371jacobs# ifdef WIN32
355b4669e025ff377602b6fc7caaf30dbc218371jacobs addr->ipv6.sin6_port = htons((u_short)port);
355b4669e025ff377602b6fc7caaf30dbc218371jacobs# else
355b4669e025ff377602b6fc7caaf30dbc218371jacobs addr->ipv6.sin6_port = htons(port);
355b4669e025ff377602b6fc7caaf30dbc218371jacobs# endif /* WIN32 */
355b4669e025ff377602b6fc7caaf30dbc218371jacobs
355b4669e025ff377602b6fc7caaf30dbc218371jacobs memcpy((char *)&(addr->ipv6.sin6_addr), host->h_addr_list[n],
355b4669e025ff377602b6fc7caaf30dbc218371jacobs host->h_length);
355b4669e025ff377602b6fc7caaf30dbc218371jacobs addr->ipv6.sin6_family = AF_INET6;
355b4669e025ff377602b6fc7caaf30dbc218371jacobs }
355b4669e025ff377602b6fc7caaf30dbc218371jacobs else
355b4669e025ff377602b6fc7caaf30dbc218371jacobs#endif /* AF_INET6 */
355b4669e025ff377602b6fc7caaf30dbc218371jacobs#ifdef AF_LOCAL
355b4669e025ff377602b6fc7caaf30dbc218371jacobs if (host->h_addrtype == AF_LOCAL)
355b4669e025ff377602b6fc7caaf30dbc218371jacobs {
355b4669e025ff377602b6fc7caaf30dbc218371jacobs addr->un.sun_family = AF_LOCAL;
355b4669e025ff377602b6fc7caaf30dbc218371jacobs strlcpy(addr->un.sun_path, host->h_addr_list[n], sizeof(addr->un.sun_path));
355b4669e025ff377602b6fc7caaf30dbc218371jacobs }
355b4669e025ff377602b6fc7caaf30dbc218371jacobs else
355b4669e025ff377602b6fc7caaf30dbc218371jacobs#endif /* AF_LOCAL */
355b4669e025ff377602b6fc7caaf30dbc218371jacobs if (host->h_addrtype == AF_INET)
355b4669e025ff377602b6fc7caaf30dbc218371jacobs {
355b4669e025ff377602b6fc7caaf30dbc218371jacobs# ifdef WIN32
355b4669e025ff377602b6fc7caaf30dbc218371jacobs addr->ipv4.sin_port = htons((u_short)port);
355b4669e025ff377602b6fc7caaf30dbc218371jacobs# else
355b4669e025ff377602b6fc7caaf30dbc218371jacobs addr->ipv4.sin_port = htons(port);
355b4669e025ff377602b6fc7caaf30dbc218371jacobs# endif /* WIN32 */
355b4669e025ff377602b6fc7caaf30dbc218371jacobs
355b4669e025ff377602b6fc7caaf30dbc218371jacobs memcpy((char *)&(addr->ipv4.sin_addr), host->h_addr_list[n],
355b4669e025ff377602b6fc7caaf30dbc218371jacobs host->h_length);
355b4669e025ff377602b6fc7caaf30dbc218371jacobs addr->ipv4.sin_family = AF_INET;
355b4669e025ff377602b6fc7caaf30dbc218371jacobs }
355b4669e025ff377602b6fc7caaf30dbc218371jacobs}
355b4669e025ff377602b6fc7caaf30dbc218371jacobs
355b4669e025ff377602b6fc7caaf30dbc218371jacobs
355b4669e025ff377602b6fc7caaf30dbc218371jacobs/*
355b4669e025ff377602b6fc7caaf30dbc218371jacobs * 'httpAddrLocalhost()' - Check for the local loopback address.
355b4669e025ff377602b6fc7caaf30dbc218371jacobs */
355b4669e025ff377602b6fc7caaf30dbc218371jacobs
355b4669e025ff377602b6fc7caaf30dbc218371jacobsint /* O - 1 if local host, 0 otherwise */
355b4669e025ff377602b6fc7caaf30dbc218371jacobshttpAddrLocalhost(const http_addr_t *addr)
355b4669e025ff377602b6fc7caaf30dbc218371jacobs /* I - Address to check */
355b4669e025ff377602b6fc7caaf30dbc218371jacobs{
355b4669e025ff377602b6fc7caaf30dbc218371jacobs#ifdef AF_INET6
355b4669e025ff377602b6fc7caaf30dbc218371jacobs if (addr->addr.sa_family == AF_INET6 &&
355b4669e025ff377602b6fc7caaf30dbc218371jacobs IN6_IS_ADDR_LOOPBACK(&(addr->ipv6.sin6_addr)))
355b4669e025ff377602b6fc7caaf30dbc218371jacobs return (1);
355b4669e025ff377602b6fc7caaf30dbc218371jacobs#endif /* AF_INET6 */
355b4669e025ff377602b6fc7caaf30dbc218371jacobs
355b4669e025ff377602b6fc7caaf30dbc218371jacobs#ifdef AF_LOCAL
355b4669e025ff377602b6fc7caaf30dbc218371jacobs if (addr->addr.sa_family == AF_LOCAL)
355b4669e025ff377602b6fc7caaf30dbc218371jacobs return (1);
355b4669e025ff377602b6fc7caaf30dbc218371jacobs#endif /* AF_LOCAL */
355b4669e025ff377602b6fc7caaf30dbc218371jacobs
355b4669e025ff377602b6fc7caaf30dbc218371jacobs if (addr->addr.sa_family == AF_INET &&
355b4669e025ff377602b6fc7caaf30dbc218371jacobs ntohl(addr->ipv4.sin_addr.s_addr) == 0x7f000001)
355b4669e025ff377602b6fc7caaf30dbc218371jacobs return (1);
355b4669e025ff377602b6fc7caaf30dbc218371jacobs
355b4669e025ff377602b6fc7caaf30dbc218371jacobs return (0);
355b4669e025ff377602b6fc7caaf30dbc218371jacobs}
355b4669e025ff377602b6fc7caaf30dbc218371jacobs
355b4669e025ff377602b6fc7caaf30dbc218371jacobs
355b4669e025ff377602b6fc7caaf30dbc218371jacobs#ifdef __sgi
355b4669e025ff377602b6fc7caaf30dbc218371jacobs# define ADDR_CAST (struct sockaddr *)
355b4669e025ff377602b6fc7caaf30dbc218371jacobs#else
355b4669e025ff377602b6fc7caaf30dbc218371jacobs# define ADDR_CAST (char *)
355b4669e025ff377602b6fc7caaf30dbc218371jacobs#endif /* __sgi */
355b4669e025ff377602b6fc7caaf30dbc218371jacobs
355b4669e025ff377602b6fc7caaf30dbc218371jacobs
355b4669e025ff377602b6fc7caaf30dbc218371jacobs/*
355b4669e025ff377602b6fc7caaf30dbc218371jacobs * 'httpAddrLookup()' - Lookup the hostname associated with the address.
355b4669e025ff377602b6fc7caaf30dbc218371jacobs */
355b4669e025ff377602b6fc7caaf30dbc218371jacobs
355b4669e025ff377602b6fc7caaf30dbc218371jacobschar * /* O - Host name */
355b4669e025ff377602b6fc7caaf30dbc218371jacobshttpAddrLookup(const http_addr_t *addr, /* I - Address to lookup */
355b4669e025ff377602b6fc7caaf30dbc218371jacobs char *name, /* I - Host name buffer */
355b4669e025ff377602b6fc7caaf30dbc218371jacobs int namelen) /* I - Size of name buffer */
355b4669e025ff377602b6fc7caaf30dbc218371jacobs{
355b4669e025ff377602b6fc7caaf30dbc218371jacobs struct hostent *host; /* Host from name service */
355b4669e025ff377602b6fc7caaf30dbc218371jacobs
355b4669e025ff377602b6fc7caaf30dbc218371jacobs
355b4669e025ff377602b6fc7caaf30dbc218371jacobs DEBUG_printf(("httpAddrLookup(addr=%p, name=%p, namelen=%d)\n",
355b4669e025ff377602b6fc7caaf30dbc218371jacobs addr, name, namelen));
355b4669e025ff377602b6fc7caaf30dbc218371jacobs
355b4669e025ff377602b6fc7caaf30dbc218371jacobs#ifdef AF_INET6
355b4669e025ff377602b6fc7caaf30dbc218371jacobs if (addr->addr.sa_family == AF_INET6)
355b4669e025ff377602b6fc7caaf30dbc218371jacobs host = gethostbyaddr(ADDR_CAST &(addr->ipv6.sin6_addr),
355b4669e025ff377602b6fc7caaf30dbc218371jacobs sizeof(struct in6_addr), AF_INET6);
355b4669e025ff377602b6fc7caaf30dbc218371jacobs else
355b4669e025ff377602b6fc7caaf30dbc218371jacobs#endif /* AF_INET6 */
355b4669e025ff377602b6fc7caaf30dbc218371jacobs#ifdef AF_LOCAL
355b4669e025ff377602b6fc7caaf30dbc218371jacobs if (addr->addr.sa_family == AF_LOCAL)
355b4669e025ff377602b6fc7caaf30dbc218371jacobs {
355b4669e025ff377602b6fc7caaf30dbc218371jacobs strlcpy(name, addr->un.sun_path, namelen);
355b4669e025ff377602b6fc7caaf30dbc218371jacobs return (name);
355b4669e025ff377602b6fc7caaf30dbc218371jacobs }
355b4669e025ff377602b6fc7caaf30dbc218371jacobs else
355b4669e025ff377602b6fc7caaf30dbc218371jacobs#endif /* AF_LOCAL */
355b4669e025ff377602b6fc7caaf30dbc218371jacobs if (addr->addr.sa_family == AF_INET)
355b4669e025ff377602b6fc7caaf30dbc218371jacobs host = gethostbyaddr(ADDR_CAST &(addr->ipv4.sin_addr),
355b4669e025ff377602b6fc7caaf30dbc218371jacobs sizeof(struct in_addr), AF_INET);
355b4669e025ff377602b6fc7caaf30dbc218371jacobs else
355b4669e025ff377602b6fc7caaf30dbc218371jacobs host = NULL;
355b4669e025ff377602b6fc7caaf30dbc218371jacobs
355b4669e025ff377602b6fc7caaf30dbc218371jacobs if (host == NULL)
355b4669e025ff377602b6fc7caaf30dbc218371jacobs {
355b4669e025ff377602b6fc7caaf30dbc218371jacobs httpAddrString(addr, name, namelen);
355b4669e025ff377602b6fc7caaf30dbc218371jacobs return (NULL);
355b4669e025ff377602b6fc7caaf30dbc218371jacobs }
355b4669e025ff377602b6fc7caaf30dbc218371jacobs
355b4669e025ff377602b6fc7caaf30dbc218371jacobs strlcpy(name, host->h_name, namelen);
355b4669e025ff377602b6fc7caaf30dbc218371jacobs
355b4669e025ff377602b6fc7caaf30dbc218371jacobs return (name);
355b4669e025ff377602b6fc7caaf30dbc218371jacobs}
355b4669e025ff377602b6fc7caaf30dbc218371jacobs
355b4669e025ff377602b6fc7caaf30dbc218371jacobs
355b4669e025ff377602b6fc7caaf30dbc218371jacobs/*
355b4669e025ff377602b6fc7caaf30dbc218371jacobs * 'httpAddrString()' - Convert an IP address to a dotted string.
355b4669e025ff377602b6fc7caaf30dbc218371jacobs */
355b4669e025ff377602b6fc7caaf30dbc218371jacobs
355b4669e025ff377602b6fc7caaf30dbc218371jacobschar * /* O - IP string */
355b4669e025ff377602b6fc7caaf30dbc218371jacobshttpAddrString(const http_addr_t *addr, /* I - Address to convert */
355b4669e025ff377602b6fc7caaf30dbc218371jacobs char *s, /* I - String buffer */
355b4669e025ff377602b6fc7caaf30dbc218371jacobs int slen) /* I - Length of string */
355b4669e025ff377602b6fc7caaf30dbc218371jacobs{
355b4669e025ff377602b6fc7caaf30dbc218371jacobs DEBUG_printf(("httpAddrString(addr=%p, s=%p, slen=%d)\n",
355b4669e025ff377602b6fc7caaf30dbc218371jacobs addr, s, slen));
355b4669e025ff377602b6fc7caaf30dbc218371jacobs
355b4669e025ff377602b6fc7caaf30dbc218371jacobs#ifdef AF_INET6
355b4669e025ff377602b6fc7caaf30dbc218371jacobs if (addr->addr.sa_family == AF_INET6)
355b4669e025ff377602b6fc7caaf30dbc218371jacobs snprintf(s, slen, "%u.%u.%u.%u",
355b4669e025ff377602b6fc7caaf30dbc218371jacobs ntohl(addr->ipv6.sin6_addr.s6_addr32[0]),
355b4669e025ff377602b6fc7caaf30dbc218371jacobs ntohl(addr->ipv6.sin6_addr.s6_addr32[1]),
355b4669e025ff377602b6fc7caaf30dbc218371jacobs ntohl(addr->ipv6.sin6_addr.s6_addr32[2]),
355b4669e025ff377602b6fc7caaf30dbc218371jacobs ntohl(addr->ipv6.sin6_addr.s6_addr32[3]));
355b4669e025ff377602b6fc7caaf30dbc218371jacobs else
355b4669e025ff377602b6fc7caaf30dbc218371jacobs#endif /* AF_INET6 */
355b4669e025ff377602b6fc7caaf30dbc218371jacobs#ifdef AF_LOCAL
355b4669e025ff377602b6fc7caaf30dbc218371jacobs if (addr->addr.sa_family == AF_LOCAL)
355b4669e025ff377602b6fc7caaf30dbc218371jacobs strlcpy(s, addr->un.sun_path, slen);
355b4669e025ff377602b6fc7caaf30dbc218371jacobs else
355b4669e025ff377602b6fc7caaf30dbc218371jacobs#endif /* AF_LOCAL */
355b4669e025ff377602b6fc7caaf30dbc218371jacobs if (addr->addr.sa_family == AF_INET)
355b4669e025ff377602b6fc7caaf30dbc218371jacobs {
355b4669e025ff377602b6fc7caaf30dbc218371jacobs unsigned temp; /* Temporary address */
355b4669e025ff377602b6fc7caaf30dbc218371jacobs
355b4669e025ff377602b6fc7caaf30dbc218371jacobs
355b4669e025ff377602b6fc7caaf30dbc218371jacobs temp = ntohl(addr->ipv4.sin_addr.s_addr);
355b4669e025ff377602b6fc7caaf30dbc218371jacobs
355b4669e025ff377602b6fc7caaf30dbc218371jacobs snprintf(s, slen, "%d.%d.%d.%d", (temp >> 24) & 255,
355b4669e025ff377602b6fc7caaf30dbc218371jacobs (temp >> 16) & 255, (temp >> 8) & 255, temp & 255);
355b4669e025ff377602b6fc7caaf30dbc218371jacobs }
355b4669e025ff377602b6fc7caaf30dbc218371jacobs else
355b4669e025ff377602b6fc7caaf30dbc218371jacobs strlcpy(s, "UNKNOWN", slen);
355b4669e025ff377602b6fc7caaf30dbc218371jacobs
355b4669e025ff377602b6fc7caaf30dbc218371jacobs DEBUG_printf(("httpAddrString: returning \"%s\"...\n", s));
355b4669e025ff377602b6fc7caaf30dbc218371jacobs
355b4669e025ff377602b6fc7caaf30dbc218371jacobs return (s);
355b4669e025ff377602b6fc7caaf30dbc218371jacobs}
355b4669e025ff377602b6fc7caaf30dbc218371jacobs
355b4669e025ff377602b6fc7caaf30dbc218371jacobs
355b4669e025ff377602b6fc7caaf30dbc218371jacobs/*
355b4669e025ff377602b6fc7caaf30dbc218371jacobs * 'httpGetHostByName()' - Lookup a hostname or IP address, and return
355b4669e025ff377602b6fc7caaf30dbc218371jacobs * address records for the specified name.
355b4669e025ff377602b6fc7caaf30dbc218371jacobs */
355b4669e025ff377602b6fc7caaf30dbc218371jacobs
355b4669e025ff377602b6fc7caaf30dbc218371jacobsstruct hostent * /* O - Host entry */
355b4669e025ff377602b6fc7caaf30dbc218371jacobshttpGetHostByName(const char *name) /* I - Hostname or IP address */
355b4669e025ff377602b6fc7caaf30dbc218371jacobs{
355b4669e025ff377602b6fc7caaf30dbc218371jacobs const char *nameptr; /* Pointer into name */
355b4669e025ff377602b6fc7caaf30dbc218371jacobs unsigned ip[4]; /* IP address components */
355b4669e025ff377602b6fc7caaf30dbc218371jacobs static unsigned packed_ip; /* Packed IPv4 address */
355b4669e025ff377602b6fc7caaf30dbc218371jacobs static char *packed_ptr[2]; /* Pointer to packed address */
355b4669e025ff377602b6fc7caaf30dbc218371jacobs static struct hostent host_ip; /* Host entry for IP/domain address */
355b4669e025ff377602b6fc7caaf30dbc218371jacobs
355b4669e025ff377602b6fc7caaf30dbc218371jacobs
355b4669e025ff377602b6fc7caaf30dbc218371jacobs DEBUG_printf(("httpGetHostByName(name=\"%s\")\n", name));
355b4669e025ff377602b6fc7caaf30dbc218371jacobs
355b4669e025ff377602b6fc7caaf30dbc218371jacobs#if defined(__APPLE__)
355b4669e025ff377602b6fc7caaf30dbc218371jacobs /* OS X hack to avoid it's ocassional long delay in lookupd */
355b4669e025ff377602b6fc7caaf30dbc218371jacobs static const char sLoopback[] = "127.0.0.1";
355b4669e025ff377602b6fc7caaf30dbc218371jacobs if (strcmp(name, "localhost") == 0)
355b4669e025ff377602b6fc7caaf30dbc218371jacobs name = sLoopback;
355b4669e025ff377602b6fc7caaf30dbc218371jacobs#endif /* __APPLE__ */
355b4669e025ff377602b6fc7caaf30dbc218371jacobs
355b4669e025ff377602b6fc7caaf30dbc218371jacobs /*
355b4669e025ff377602b6fc7caaf30dbc218371jacobs * This function is needed because some operating systems have a
355b4669e025ff377602b6fc7caaf30dbc218371jacobs * buggy implementation of gethostbyname() that does not support
355b4669e025ff377602b6fc7caaf30dbc218371jacobs * IP addresses. If the first character of the name string is a
355b4669e025ff377602b6fc7caaf30dbc218371jacobs * number, then sscanf() is used to extract the IP components.
355b4669e025ff377602b6fc7caaf30dbc218371jacobs * We then pack the components into an IPv4 address manually,
355b4669e025ff377602b6fc7caaf30dbc218371jacobs * since the inet_aton() function is deprecated. We use the
355b4669e025ff377602b6fc7caaf30dbc218371jacobs * htonl() macro to get the right byte order for the address.
355b4669e025ff377602b6fc7caaf30dbc218371jacobs *
355b4669e025ff377602b6fc7caaf30dbc218371jacobs * We also support domain sockets when supported by the underlying
355b4669e025ff377602b6fc7caaf30dbc218371jacobs * OS...
355b4669e025ff377602b6fc7caaf30dbc218371jacobs */
355b4669e025ff377602b6fc7caaf30dbc218371jacobs
355b4669e025ff377602b6fc7caaf30dbc218371jacobs#ifdef AF_LOCAL
355b4669e025ff377602b6fc7caaf30dbc218371jacobs if (name[0] == '/')
355b4669e025ff377602b6fc7caaf30dbc218371jacobs {
355b4669e025ff377602b6fc7caaf30dbc218371jacobs /*
355b4669e025ff377602b6fc7caaf30dbc218371jacobs * A domain socket address, so make an AF_LOCAL entry and return it...
355b4669e025ff377602b6fc7caaf30dbc218371jacobs */
355b4669e025ff377602b6fc7caaf30dbc218371jacobs
355b4669e025ff377602b6fc7caaf30dbc218371jacobs host_ip.h_name = (char *)name;
355b4669e025ff377602b6fc7caaf30dbc218371jacobs host_ip.h_aliases = NULL;
355b4669e025ff377602b6fc7caaf30dbc218371jacobs host_ip.h_addrtype = AF_LOCAL;
355b4669e025ff377602b6fc7caaf30dbc218371jacobs host_ip.h_length = strlen(name) + 1;
355b4669e025ff377602b6fc7caaf30dbc218371jacobs host_ip.h_addr_list = packed_ptr;
355b4669e025ff377602b6fc7caaf30dbc218371jacobs packed_ptr[0] = (char *)name;
355b4669e025ff377602b6fc7caaf30dbc218371jacobs packed_ptr[1] = NULL;
355b4669e025ff377602b6fc7caaf30dbc218371jacobs
355b4669e025ff377602b6fc7caaf30dbc218371jacobs DEBUG_puts("httpGetHostByName: returning domain socket address...");
355b4669e025ff377602b6fc7caaf30dbc218371jacobs
355b4669e025ff377602b6fc7caaf30dbc218371jacobs return (&host_ip);
355b4669e025ff377602b6fc7caaf30dbc218371jacobs }
355b4669e025ff377602b6fc7caaf30dbc218371jacobs#endif /* AF_LOCAL */
355b4669e025ff377602b6fc7caaf30dbc218371jacobs
355b4669e025ff377602b6fc7caaf30dbc218371jacobs for (nameptr = name; isdigit(*nameptr & 255) || *nameptr == '.'; nameptr ++);
355b4669e025ff377602b6fc7caaf30dbc218371jacobs
355b4669e025ff377602b6fc7caaf30dbc218371jacobs if (!*nameptr)
355b4669e025ff377602b6fc7caaf30dbc218371jacobs {
355b4669e025ff377602b6fc7caaf30dbc218371jacobs /*
355b4669e025ff377602b6fc7caaf30dbc218371jacobs * We have an IP address; break it up and provide the host entry
355b4669e025ff377602b6fc7caaf30dbc218371jacobs * to the caller. Currently only supports IPv4 addresses, although
355b4669e025ff377602b6fc7caaf30dbc218371jacobs * it should be trivial to support IPv6 in CUPS 1.2.
355b4669e025ff377602b6fc7caaf30dbc218371jacobs */
355b4669e025ff377602b6fc7caaf30dbc218371jacobs
355b4669e025ff377602b6fc7caaf30dbc218371jacobs if (sscanf(name, "%u.%u.%u.%u", ip, ip + 1, ip + 2, ip + 3) != 4)
355b4669e025ff377602b6fc7caaf30dbc218371jacobs return (NULL); /* Must have 4 numbers */
355b4669e025ff377602b6fc7caaf30dbc218371jacobs
355b4669e025ff377602b6fc7caaf30dbc218371jacobs if (ip[0] > 255 || ip[1] > 255 || ip[2] > 255 || ip[3] > 255)
355b4669e025ff377602b6fc7caaf30dbc218371jacobs return (NULL); /* Invalid byte ranges! */
355b4669e025ff377602b6fc7caaf30dbc218371jacobs
355b4669e025ff377602b6fc7caaf30dbc218371jacobs packed_ip = htonl(((((((ip[0] << 8) | ip[1]) << 8) | ip[2]) << 8) | ip[3]));
355b4669e025ff377602b6fc7caaf30dbc218371jacobs
355b4669e025ff377602b6fc7caaf30dbc218371jacobs /*
355b4669e025ff377602b6fc7caaf30dbc218371jacobs * Fill in the host entry and return it...
355b4669e025ff377602b6fc7caaf30dbc218371jacobs */
355b4669e025ff377602b6fc7caaf30dbc218371jacobs
355b4669e025ff377602b6fc7caaf30dbc218371jacobs host_ip.h_name = (char *)name;
355b4669e025ff377602b6fc7caaf30dbc218371jacobs host_ip.h_aliases = NULL;
355b4669e025ff377602b6fc7caaf30dbc218371jacobs host_ip.h_addrtype = AF_INET;
355b4669e025ff377602b6fc7caaf30dbc218371jacobs host_ip.h_length = 4;
355b4669e025ff377602b6fc7caaf30dbc218371jacobs host_ip.h_addr_list = packed_ptr;
355b4669e025ff377602b6fc7caaf30dbc218371jacobs packed_ptr[0] = (char *)(&packed_ip);
355b4669e025ff377602b6fc7caaf30dbc218371jacobs packed_ptr[1] = NULL;
355b4669e025ff377602b6fc7caaf30dbc218371jacobs
355b4669e025ff377602b6fc7caaf30dbc218371jacobs DEBUG_puts("httpGetHostByName: returning IPv4 address...");
355b4669e025ff377602b6fc7caaf30dbc218371jacobs
355b4669e025ff377602b6fc7caaf30dbc218371jacobs return (&host_ip);
355b4669e025ff377602b6fc7caaf30dbc218371jacobs }
355b4669e025ff377602b6fc7caaf30dbc218371jacobs else
355b4669e025ff377602b6fc7caaf30dbc218371jacobs {
355b4669e025ff377602b6fc7caaf30dbc218371jacobs /*
355b4669e025ff377602b6fc7caaf30dbc218371jacobs * Use the gethostbyname() function to get the IP address for
355b4669e025ff377602b6fc7caaf30dbc218371jacobs * the name...
355b4669e025ff377602b6fc7caaf30dbc218371jacobs */
355b4669e025ff377602b6fc7caaf30dbc218371jacobs
355b4669e025ff377602b6fc7caaf30dbc218371jacobs DEBUG_puts("httpGetHostByName: returning domain lookup address(es)...");
355b4669e025ff377602b6fc7caaf30dbc218371jacobs
355b4669e025ff377602b6fc7caaf30dbc218371jacobs return (gethostbyname(name));
355b4669e025ff377602b6fc7caaf30dbc218371jacobs }
355b4669e025ff377602b6fc7caaf30dbc218371jacobs}
355b4669e025ff377602b6fc7caaf30dbc218371jacobs
355b4669e025ff377602b6fc7caaf30dbc218371jacobs
355b4669e025ff377602b6fc7caaf30dbc218371jacobs/*
355b4669e025ff377602b6fc7caaf30dbc218371jacobs * End of "$Id: http-addr.c 148 2006-04-25 16:54:17Z njacobs $".
355b4669e025ff377602b6fc7caaf30dbc218371jacobs */