ypresolv_proc.c revision f48205be61a214698b763ff550ab9e657525104c
/*
* 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 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/*
*
*/
#pragma ident "%Z%%M% %I% %E% SMI"
/* ******************** include headers ****************************** */
#include <netdb.h>
#include <ctype.h>
#include <syslog.h>
#include <netdir.h>
#include <stdlib.h>
#include <strings.h>
#include "../resolv_common.h"
#include "prnt.h"
#include "nres.h"
#define RESP_NOW 0
#define RESP_LATER 2
/*
* Cache entries for storing rpc.nisd req and resolv req info
*/
struct cache_ent {
char *map;
int h_errno;
unsigned long xid;
unsigned long ttl;
struct cache_ent *next_cache_ent;
};
int lookup_AF_type(struct cache_ent *);
/* ******************** static vars and funcs ************************ */
int);
static void free_cache_ent(struct cache_ent *x);
/* ******************** extern vars and funcs ************************ */
extern int verbose;
extern SVCXPRT *reply_xprt4;
extern SVCXPRT *reply_xprt6;
static void
{
struct ypresp_val resp;
int i;
/* Set the reply_xprt: xid and caller here, to fit yp_matchdns() */
} else {
/*
* This doesn't make much sense, but the for some reason
* the caller converted req->ip to host byte order, and in
* the name of backward compatibility...
*/
}
return;
}
return;
}
/*
* Set su_tudata.addr for sendreply() t_sendudata()
* since we never did a recv on this unreg'ed xprt.
*/
if (!bd) { /* just set maxlen and buf once */
}
if (!svc_sendreply(transp,
}
}
void
{
struct ypfwdreq_key4 req4;
struct ypfwdreq_key6 req6;
case NULLPROC:
break;
case YPDNSPROC4:
return;
}
/* args were ok: don't wait for resolver */
exit(1);
}
break;
case YPDNSPROC6:
return;
}
/* args were ok: don't wait for resolver */
exit(1);
}
break;
default:
break;
}
}
static struct cache_ent *
char *map;
{
int secs;
return (NULL);
return (NULL);
return (NULL);
/* check for expiration */
else
"bykey:stale cache_ent flushed %x.\n", chl);
/* deleteing the first element is tricky */
if (chl == cache_head) {
prev = cache_head;
chl = cache_head;
continue;
} else {
/* deleteing a middle element */
continue;
}
/* supress trailing null */
/* move to beginning */
if (chl != cache_head) {
cache_head = chl;
}
return (chl);
}
}
}
return (NULL);
}
static struct cache_ent *
char *map;
{
return (NULL);
return (NULL);
}
return (NULL);
}
/* delete trailing null */
cache_head = chl;
return (chl);
}
static struct cache_ent *
struct cache_ent *x;
{
if (x == cache_head) {
x->next_cache_ent = NULL;
return (x);
}
if (chl == x) {
/* deq it */
return (chl);
}
}
return (NULL); /* bad */
}
static void
struct cache_ent *x;
{
if (x == NULL)
return;
if (x->map)
free(x);
}
static ulong_t
{
return (0);
return (old_xid);
}
static int
char *map; /* map name */
unsigned *statusp; /* returns the status */
{
struct nres *h;
int try_again;
int af_type;
try_again = 0;
/*
* Skip the domain resolution if: 1. it is not turned on 2. map other
* than hosts.byXXX 3. a null string (usingypmap() likes to send
* these) 4. a single control character (usingypmap() again)
*/
return (RESP_NOW);
}
if (chl) {
try_again = 1;
/* update xid */
if (transp) {
}
return (RESP_LATER); /* drop */
}
case NO_RECOVERY:
#ifndef NO_DATA
#define NO_DATA NO_ADDRESS
#endif
case NO_DATA:
case HOST_NOT_FOUND:
return (RESP_NOW);
case TRY_AGAIN:
try_again = 1;
break;
case 0:
return (RESP_NOW);
}
break;
default:
break;
}
}
/* have a trier activated -- tell them to try again */
if (try_again) {
/* try_again overloaded */
return (RESP_NOW);
}
}
if (chl) {
} else
perror("new_cache_ent failed");
return (RESP_NOW);
}
else {
== -1) {
return (RESP_NOW);
}
h = nres_gethostbyaddr(
} else {
return (RESP_NOW);
}
}
if (h == 0) { /* definite immediate reject */
return (RESP_NOW);
} else if (h == (struct nres *)-1) {
perror("nres failed\n");
return (RESP_NOW);
} else {
/* should stash transport so my_done can answer */
if (try_again) {
/* try_again overloaded */
return (RESP_NOW);
}
if (transp) {
}
return (RESP_LATER);
}
}
static void
void *n; /* opaque */
struct hostent *h;
int errcode;
{
static char buf[1024];
int i;
unsigned long xid_hold;
struct ypresp_val resp;
char uaddr[sizeof (struct sockaddr_in6)];
if (h == NULL) {
else
} else {
/* build the return list */
for (i = 0; h->h_addr_list[i]; i++) {
(void *) (h->h_addr_list[i]) :
(void *) (h->h_addr_list[i]),
break;
}
/* remove trailing newline */
}
perror("my_done");
return;
}
}
/* try to answer here */
(char *)&resp)) {
return;
}
addrp = &caller_hold;
}
}
/*
* this routine returns the DNS query type:
* T_A: IPv4
* T_AAAA: IPv6
*/
int
{
return (T_AAAA);
return (T_PTR);
}
return (T_A);
}
/*
* this routine returns the AF type for the request:
* AF_INET: ipv4
* AF_INET6: IPv6
*/
int
{
return (AF_INET6);
}
return (AF_INET);
}