getaddrinfo.c revision af5073d03288a53b646ec3b807ac25ced64d7879
11e9368a226272085c337e9e74b79808c16fbdbaTinderbox User * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC")
5a4557e8de2951a2796676b5ec4b6a90caa5be14Mark Andrews * Copyright (C) 1999-2001 Internet Software Consortium.
4a14ce5ba00ab7bc55c99ffdcf59c7a4ab902721Automatic Updater * This code is derived from software contributed to ISC by
5a4557e8de2951a2796676b5ec4b6a90caa5be14Mark Andrews * Berkeley Software Design, Inc.
5a4557e8de2951a2796676b5ec4b6a90caa5be14Mark Andrews * Permission to use, copy, modify, and distribute this software for any
5a4557e8de2951a2796676b5ec4b6a90caa5be14Mark Andrews * purpose with or without fee is hereby granted, provided that the above
5a4557e8de2951a2796676b5ec4b6a90caa5be14Mark Andrews * copyright notice and this permission notice appear in all copies.
5a4557e8de2951a2796676b5ec4b6a90caa5be14Mark Andrews * THE SOFTWARE IS PROVIDED "AS IS" AND ISC AND BERKELEY SOFTWARE DESIGN, INC.
5a4557e8de2951a2796676b5ec4b6a90caa5be14Mark Andrews * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
5a4557e8de2951a2796676b5ec4b6a90caa5be14Mark Andrews * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE
5a4557e8de2951a2796676b5ec4b6a90caa5be14Mark Andrews * FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
5a4557e8de2951a2796676b5ec4b6a90caa5be14Mark Andrews * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
5a4557e8de2951a2796676b5ec4b6a90caa5be14Mark Andrews * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
5a4557e8de2951a2796676b5ec4b6a90caa5be14Mark Andrews * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User/* $Id: getaddrinfo.c,v 1.43 2004/03/05 05:48:26 marka Exp $ */
5a4557e8de2951a2796676b5ec4b6a90caa5be14Mark Andrews#define SIN(addr) ((struct sockaddr_in *)(addr))
5a4557e8de2951a2796676b5ec4b6a90caa5be14Mark Andrews#define SUN(addr) ((struct sockaddr_un *)(addr))
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox Userstatic int get_local(const char *name, int socktype, struct addrinfo **res);
5a4557e8de2951a2796676b5ec4b6a90caa5be14Mark Andrewsstatic int add_ipv4(const char *hostname, int flags, struct addrinfo **aip,
5a4557e8de2951a2796676b5ec4b6a90caa5be14Mark Andrewsstatic int add_ipv6(const char *hostname, int flags, struct addrinfo **aip,
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox Userstatic void set_order(int, int (**)(const char *, int, struct addrinfo **,
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt#define ISC_AI_MASK (AI_PASSIVE|AI_CANONNAME|AI_NUMERICHOST)
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox Userlwres_getaddrinfo(const char *hostname, const char *servname,
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt const struct addrinfo *hints, struct addrinfo **res)
5a4557e8de2951a2796676b5ec4b6a90caa5be14Mark Andrews int (*net_order[FOUND_MAX+1])(const char *, int, struct addrinfo **,
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User if (hints->ai_addrlen || hints->ai_canonname ||
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt * First, deal with AF_LOCAL. If the family was not set,
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt * then assume AF_LOCAL if the first character of the
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User (family == AF_LOCAL || (family == 0 && *hostname == '/')))
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt (family == AF_LOCAL || (family == 0 && *servname == '/')))
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User * Ok, only AF_INET and AF_INET6 left.
72938578c985138165e7a4b0a38f16daacbad95eAutomatic Updater * First, look up the service name (port) if it was
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User * requested. If the socket type wasn't specified, then
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt * try and figure it out.
dba3c818ae00b10388d31703e86a28415db398acTinderbox User if (*e == '\0') {
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User * Next, deal with just a service name, and no hostname.
97e74139b19368e385a3564746d42db70879195eAutomatic Updater * (we verified that one of them was non-null up above).
43b94483957d3168796a816ed86cf097518817dcTinderbox User if (hostname == NULL && (flags & AI_PASSIVE) != 0) {
dba3c818ae00b10388d31703e86a28415db398acTinderbox User ai = ai_alloc(AF_INET, sizeof(struct sockaddr_in));
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User ai = ai_alloc(AF_INET6, sizeof(struct sockaddr_in6));
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User * If the family isn't specified or AI_NUMERICHOST specified,
5a4557e8de2951a2796676b5ec4b6a90caa5be14Mark Andrews * check first to see if it is a numeric address.
f7b41fd9291b8f4dba27e2b57e1d93f0913a4f1dMark Andrews * Though the gethostbyname2() routine
f7b41fd9291b8f4dba27e2b57e1d93f0913a4f1dMark Andrews * will recognize numeric addresses, it will only recognize
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt * the format that it is being called for. Thus, a numeric
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User * AF_INET address will be treated by the AF_INET6 call as
e2e4d321999340802f77adaacd19c797d04b4b95Automatic Updater * a domain name, and vice versa. Checking for both numerics
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User * here avoids that.
5a4557e8de2951a2796676b5ec4b6a90caa5be14Mark Andrews * Scope identifier portion.
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt * Vendors may want to support non-numeric
14a656f94b1fd0ababd84a772228dfa52276ba15Evan Hunt * scopeid around here.
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User if (lwres_net_pton(AF_INET, hostname, (struct in_addr *)abuf)
5a4557e8de2951a2796676b5ec4b6a90caa5be14Mark Andrews * Convert to a V4 mapped address.
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User memcpy(&a6->s6_addr[12], &a6->s6_addr[0], 4);
5a4557e8de2951a2796676b5ec4b6a90caa5be14Mark Andrews addroff = (char *)(&SIN(0)->sin_addr) - (char *)0;
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User addroff = (char *)(&SIN6(0)->sin6_addr) - (char *)0;
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User } else if (lwres_net_pton(AF_INET6, hostname, abuf) == 1) {
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User addroff = (char *)(&SIN6(0)->sin6_addr) - (char *)0;
fd2597f75693a2279fdf588bd40dfe2407c42028Tinderbox User memcpy((char *)ai->ai_addr + addroff, abuf, addrsize);
5a4557e8de2951a2796676b5ec4b6a90caa5be14Mark Andrews /* XXX raise error? */
5a4557e8de2951a2796676b5ec4b6a90caa5be14Mark Andrews for (i = 0; i < FOUND_MAX; i++) {
if (err != 0)
return (err);
return (EAI_NODATA);
done:
return (NULL);
sc = *s;
*stringp = s;
return (string);
return (string);
int found;
if (family) {
switch (family) {
case AF_INET:
case AF_INET6:
found = 0;
int result = 0;
goto cleanup;
return (result);
int result = 0;
goto cleanup;
return (result);
#ifdef AF_LOCAL
if (socktype == 0)
return (EAI_SOCKTYPE);
return (EAI_MEMORY);
static struct addrinfo *
return (NULL);
return (NULL);
#ifdef LWRES_PLATFORM_HAVESALEN
return (ai);
static struct addrinfo *
return (NULL);
return (ai);
return (ai);
static struct addrinfo *
return (nai);