Path: blob/main/contrib/ldns/compat/fake-rfc2553.c
39482 views
/* From openssh 4.3p2 filename openbsd-compat/fake-rfc2553.h */1/*2* Copyright (C) 2000-2003 Damien Miller. All rights reserved.3* Copyright (C) 1999 WIDE Project. All rights reserved.4*5* Redistribution and use in source and binary forms, with or without6* modification, are permitted provided that the following conditions7* are met:8* 1. Redistributions of source code must retain the above copyright9* notice, this list of conditions and the following disclaimer.10* 2. Redistributions in binary form must reproduce the above copyright11* notice, this list of conditions and the following disclaimer in the12* documentation and/or other materials provided with the distribution.13* 3. Neither the name of the project nor the names of its contributors14* may be used to endorse or promote products derived from this software15* without specific prior written permission.16*17* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND18* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE19* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE20* ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE21* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL22* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS23* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)24* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT25* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY26* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF27* SUCH DAMAGE.28*/2930/*31* Pseudo-implementation of RFC2553 name / address resolution functions32*33* But these functions are not implemented correctly. The minimum subset34* is implemented for ssh use only. For example, this routine assumes35* that ai_family is AF_INET. Don't use it for another purpose.36*/3738#include <ldns/config.h>39#include <ldns/common.h>40#include <unistd.h>41#include <string.h>42#include <stdio.h>43#include <stdlib.h>44#include "compat/fake-rfc2553.h"4546#ifndef HAVE_GETNAMEINFO47int getnameinfo(const struct sockaddr *sa, size_t ATTR_UNUSED(salen), char *host,48size_t hostlen, char *serv, size_t servlen, int flags)49{50struct sockaddr_in *sin = (struct sockaddr_in *)sa;51struct hostent *hp;52char tmpserv[16];5354if (serv != NULL) {55snprintf(tmpserv, sizeof(tmpserv), "%d", ntohs(sin->sin_port));56if (strlcpy(serv, tmpserv, servlen) >= servlen)57return (EAI_MEMORY);58}5960if (host != NULL) {61if (flags & NI_NUMERICHOST) {62if (strlcpy(host, inet_ntoa(sin->sin_addr),63hostlen) >= hostlen)64return (EAI_MEMORY);65else66return (0);67} else {68hp = gethostbyaddr((char *)&sin->sin_addr,69sizeof(struct in_addr), AF_INET);70if (hp == NULL)71return (EAI_NODATA);7273if (strlcpy(host, hp->h_name, hostlen) >= hostlen)74return (EAI_MEMORY);75else76return (0);77}78}79return (0);80}81#endif /* !HAVE_GETNAMEINFO */8283#ifndef HAVE_GAI_STRERROR84#ifdef HAVE_CONST_GAI_STRERROR_PROTO85const char *86#else87char *88#endif89gai_strerror(int err)90{91switch (err) {92case EAI_NODATA:93return ("no address associated with name");94case EAI_MEMORY:95return ("memory allocation failure.");96case EAI_NONAME:97return ("nodename nor servname provided, or not known");98default:99return ("unknown/invalid error.");100}101}102#endif /* !HAVE_GAI_STRERROR */103104#ifndef HAVE_FREEADDRINFO105void106freeaddrinfo(struct addrinfo *ai)107{108struct addrinfo *next;109110for(; ai != NULL;) {111next = ai->ai_next;112free(ai);113ai = next;114}115}116#endif /* !HAVE_FREEADDRINFO */117118#ifndef HAVE_GETADDRINFO119static struct120addrinfo *malloc_ai(int port, u_long addr, const struct addrinfo *hints)121{122struct addrinfo *ai;123124ai = malloc(sizeof(*ai) + sizeof(struct sockaddr_in));125if (ai == NULL)126return (NULL);127128memset(ai, '\0', sizeof(*ai) + sizeof(struct sockaddr_in));129130ai->ai_addr = (struct sockaddr *)(ai + 1);131/* XXX -- ssh doesn't use sa_len */132ai->ai_addrlen = sizeof(struct sockaddr_in);133ai->ai_addr->sa_family = ai->ai_family = AF_INET;134135((struct sockaddr_in *)(ai)->ai_addr)->sin_port = port;136((struct sockaddr_in *)(ai)->ai_addr)->sin_addr.s_addr = addr;137138/* XXX: the following is not generally correct, but does what we want */139if (hints->ai_socktype)140ai->ai_socktype = hints->ai_socktype;141else142ai->ai_socktype = SOCK_STREAM;143144if (hints->ai_protocol)145ai->ai_protocol = hints->ai_protocol;146147return (ai);148}149150int151getaddrinfo(const char *hostname, const char *servname,152const struct addrinfo *hints, struct addrinfo **res)153{154struct hostent *hp;155struct servent *sp;156struct in_addr in;157int i;158long int port;159u_long addr;160161port = 0;162if (servname != NULL) {163char *cp;164165port = strtol(servname, &cp, 10);166if (port > 0 && port <= 65535 && *cp == '\0')167port = htons(port);168else if ((sp = getservbyname(servname, NULL)) != NULL)169port = sp->s_port;170else171port = 0;172}173174if (hints && hints->ai_flags & AI_PASSIVE) {175addr = htonl(0x00000000);176if (hostname && inet_aton(hostname, &in) != 0)177addr = in.s_addr;178*res = malloc_ai(port, addr, hints);179if (*res == NULL)180return (EAI_MEMORY);181return (0);182}183184if (!hostname) {185*res = malloc_ai(port, htonl(0x7f000001), hints);186if (*res == NULL)187return (EAI_MEMORY);188return (0);189}190191if (inet_aton(hostname, &in)) {192*res = malloc_ai(port, in.s_addr, hints);193if (*res == NULL)194return (EAI_MEMORY);195return (0);196}197198/* Don't try DNS if AI_NUMERICHOST is set */199if (hints && hints->ai_flags & AI_NUMERICHOST)200return (EAI_NONAME);201202hp = gethostbyname(hostname);203if (hp && hp->h_name && hp->h_name[0] && hp->h_addr_list[0]) {204struct addrinfo *cur, *prev;205206cur = prev = *res = NULL;207for (i = 0; hp->h_addr_list[i]; i++) {208struct in_addr *in = (struct in_addr *)hp->h_addr_list[i];209210cur = malloc_ai(port, in->s_addr, hints);211if (cur == NULL) {212if (*res != NULL)213freeaddrinfo(*res);214return (EAI_MEMORY);215}216if (prev)217prev->ai_next = cur;218else219*res = cur;220221prev = cur;222}223return (0);224}225226return (EAI_NODATA);227}228#endif /* !HAVE_GETADDRINFO */229230231