ngethostbyname.c revision 7f159024d938d3699c5fadbaf3c1e06639e95c04
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
/* Taken from 4.1.3 ypserv resolver code. */
#include <ctype.h>
#include <netdb.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <resolv.h>
#include <syslog.h>
#include "nres.h"
#include "prnt.h"
#ifndef NO_DATA
#define NO_DATA NO_ADDRESS
#endif
static void nres_abort_xmit(struct nres *);
static struct nres *nres_setup(char *,
struct cache_ent *);
static int nres_dosrch(struct nres *);
static int nres_register(struct nres *, int);
extern int lookup_T_type(struct cache_ent *);
/*
* these two routines return immediate errors in h_errno and null
* if they fail or the return a struct nres
*/
struct nres *
char *name;
void (*handler) ();
{
char *cp;
/*
* a dot.
*/
/* CONSTCOND */
while (1) {
if (!*cp) {
if (*--cp == '.')
break;
return ((struct nres *)0);
}
break;
cp++;
}
}
if (nres_dosrch(temp) >= 0)
return (temp);
else {
if (temp->udp_socket >= 0)
if (temp->tcp_socket >= 0)
return ((struct nres *)0);
}
} else {
return ((struct nres *)-1);
}
}
/*
* NOTE: nres_gethostbyaddr() should never be used to lookup IPv4 mapped
* and tunnelled addresses. The client side getXbyY routine should
* have already check for this kind of lookup and translated to the
* proper IPv4 lookup.
*/
/* ARGSUSED 4 : Len is not used. */
struct nres *
char *addr;
int len;
int type;
void (*handler) ();
{
int n;
switch (type) {
case AF_INET:
break;
case AF_INET6:
for (n = IN6ADDRSZ - 1; n >= 0; n--) {
}
break;
default:
return ((struct nres *)0);
}
else
if (nres_dosrch(temp) >= 0)
return (temp);
else {
if (temp->udp_socket >= 0)
if (temp->tcp_socket >= 0)
return ((struct nres *)0);
}
} else {
return ((struct nres *)-1);
}
}
/*
* A timeout has occured -- try to retransmit, if it fails call abort_xmit to
* decide to pursue the search or give up
*/
static void
{
/* LINTED E_BAD_PTR_CAST_ALIGN */
/*
* timeout
*/
}
(void) rpc_as_unregister(as);
} else {
}
} else {
}
}
}
}
/* this advances the search with dosrch or gives up */
/* if it gives up it calls the users 'done' function */
/* this is the timeout way to call the user */
static void
{
/* called on timeout */
int give_up;
give_up = 0;
/* Timeout occurred on first attempt. */
give_up = 1;
} else if (nres_dosrch(temp) < 0)
give_up = 1;
if (give_up) {
"more srching aborted: would ret try_again to caller.\n");
if (temp->udp_socket >= 0)
if (temp->tcp_socket >= 0)
}
}
/*
* try to pursue the search by calling nres_search and nres_xmit -- if both
* work then register an asynch reply to come to nres_dorcv or a timeout to
* nres_dotimeout
*/
/*
* 0 means that the search is continuing -1 means that the search is not
* continuing h_errno has the cause.
*/
static int
{
int type;
if (nres_search(temp) >= 0) {
if (temp->question_len < 0) {
return (-1);
}
return (-1);
} else {
return (-1);
}
} else {
return (-1);
}
}
}
return (0);
}
return (-1);
}
/*
* this processes an answer received asynchronously a nres_rcv is done to
* pick up the packet, if it fails we just return, otherwise we unregister
* the fd, check the reply. If the reply has an answer we call nres_getanswer
* to get the answer, otherwise there is no answer an we call nres_dosrch to
* press the search forward, if nres_dosrch works we return. If the search
* can not be continued or if we got the answer we call the users done
* routine
*/
static void
{
int status;
struct in_addr **a;
void (*done) ();
/* LINTED E_BAD_PTR_CAST_ALIGN */
errno = 0;
if (status > 0) {
} else if (status < 0) {
return; /* keep running */
} else {
return; /* keep running */
}
(void) rpc_as_unregister(as);
/* reply part */
if (temp->answer_len < 0) {
if (errno == ECONNREFUSED) {
goto out;
}
temp->got_nodata++;
goto out;
} else {
goto out;
}
if (nres_dosrch(temp) < 0)
goto out;
return; /* keep running with new search */
out:
/* answer resolution */
}
if (theans) {
/* raise security */
theans->h_addr_list[0] =
} else {
theans->h_addr_list[0] =
}
if (temp->udp_socket >= 0)
if (temp->tcp_socket >= 0)
} else {
}
if (nres_dosrch(again) < 0) {
if (done)
if (again->udp_socket >= 0)
if (again->tcp_socket >= 0)
}
} else {
/* memory error */
if (done)
}
return;
int found_addr = FALSE;
*a; a++) {
if (done)
found_addr = TRUE;
break;
}
}
if (!found_addr) { /* weve been spoofed */
char bb[100];
"nres_gethostbyaddr: %s != %s.\n",
}
} else {
/* AF_INET6 */
if (done)
found_addr = TRUE;
break;
}
}
if (!found_addr) { /* weve been spoofed */
char bb[100];
"nres_gethostbyaddr: %s != %s.\n",
}
}
}
}
if (done)
if (temp->udp_socket >= 0)
if (temp->tcp_socket >= 0)
return; /* done running */
}
static int
nres_register(a, b)
int b;
struct nres *a;
{
a->nres_rpc_as.as_fd = b;
a->nres_rpc_as.as_userptr = (char *)a;
return (rpc_as_register(&(a->nres_rpc_as)));
}
static struct nres *
char *name;
void (*done) ();
{
return (tmp);
return (tmp);
}