1*0Sstevel@tonic-gate /*
2*0Sstevel@tonic-gate * CDDL HEADER START
3*0Sstevel@tonic-gate *
4*0Sstevel@tonic-gate * The contents of this file are subject to the terms of the
5*0Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only
6*0Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance
7*0Sstevel@tonic-gate * with the License.
8*0Sstevel@tonic-gate *
9*0Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*0Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
11*0Sstevel@tonic-gate * See the License for the specific language governing permissions
12*0Sstevel@tonic-gate * and limitations under the License.
13*0Sstevel@tonic-gate *
14*0Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
15*0Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*0Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
17*0Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
18*0Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
19*0Sstevel@tonic-gate *
20*0Sstevel@tonic-gate * CDDL HEADER END
21*0Sstevel@tonic-gate */
22*0Sstevel@tonic-gate /*
23*0Sstevel@tonic-gate * Copyright 2003 Sun Microsystems, Inc. All rights reserved.
24*0Sstevel@tonic-gate * Use is subject to license terms.
25*0Sstevel@tonic-gate */
26*0Sstevel@tonic-gate
27*0Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI"
28*0Sstevel@tonic-gate
29*0Sstevel@tonic-gate #include <stdio.h>
30*0Sstevel@tonic-gate #include <stdlib.h>
31*0Sstevel@tonic-gate #include <unistd.h>
32*0Sstevel@tonic-gate #include <ctype.h>
33*0Sstevel@tonic-gate #include <rpc/rpc.h>
34*0Sstevel@tonic-gate #include <syslog.h>
35*0Sstevel@tonic-gate #include <signal.h>
36*0Sstevel@tonic-gate #include <string.h>
37*0Sstevel@tonic-gate #include <sys/types.h>
38*0Sstevel@tonic-gate #include <sys/resource.h>
39*0Sstevel@tonic-gate #include <errno.h>
40*0Sstevel@tonic-gate #ifdef TDRPC
41*0Sstevel@tonic-gate #include <netinet/in.h>
42*0Sstevel@tonic-gate #include <arpa/inet.h>
43*0Sstevel@tonic-gate #else
44*0Sstevel@tonic-gate #include <arpa/inet.h>
45*0Sstevel@tonic-gate #include <sys/systeminfo.h>
46*0Sstevel@tonic-gate #include <netconfig.h>
47*0Sstevel@tonic-gate #include <netdir.h>
48*0Sstevel@tonic-gate #endif
49*0Sstevel@tonic-gate #include <rpcsvc/yp_prot.h>
50*0Sstevel@tonic-gate #include "ypserv_resolv_common.h"
51*0Sstevel@tonic-gate
52*0Sstevel@tonic-gate #define YPDNSVERS 2L
53*0Sstevel@tonic-gate #ifdef TDRPC
54*0Sstevel@tonic-gate #define RESOLV_EXEC_PATH "/usr/etc/rpc.nisd_resolv"
55*0Sstevel@tonic-gate #define RESOLV_EXEC_ERR "can't exec /usr/etc/rpc.nisd_resolv: %s\n"
56*0Sstevel@tonic-gate #else
57*0Sstevel@tonic-gate #define RESOLV_EXEC_PATH "/usr/sbin/rpc.nisd_resolv"
58*0Sstevel@tonic-gate #define RESOLV_EXEC_ERR "can't exec /usr/sbin/rpc.nisd_resolv: %s\n"
59*0Sstevel@tonic-gate #endif
60*0Sstevel@tonic-gate
61*0Sstevel@tonic-gate extern bool silent;
62*0Sstevel@tonic-gate int verbose;
63*0Sstevel@tonic-gate extern int resolv_pid;
64*0Sstevel@tonic-gate
65*0Sstevel@tonic-gate static int getconf(char *netid, void **handle, struct netconfig **nconf);
66*0Sstevel@tonic-gate static int getprognum(long *prognum, SVCXPRT **xprt, char *fd_str,
67*0Sstevel@tonic-gate char *prog_str, long vers, char *tp_type);
68*0Sstevel@tonic-gate
setup_resolv(bool * fwding,int * child,CLIENT ** client,char * tp_type,long prognum)69*0Sstevel@tonic-gate void setup_resolv(bool *fwding, int *child,
70*0Sstevel@tonic-gate CLIENT **client, char *tp_type, long prognum)
71*0Sstevel@tonic-gate {
72*0Sstevel@tonic-gate enum clnt_stat stat;
73*0Sstevel@tonic-gate struct timeval tv;
74*0Sstevel@tonic-gate char prog_str[15], fd_str[5];
75*0Sstevel@tonic-gate SVCXPRT *xprt = NULL;
76*0Sstevel@tonic-gate char *tp;
77*0Sstevel@tonic-gate #ifdef TDRPC
78*0Sstevel@tonic-gate struct sockaddr_in addr;
79*0Sstevel@tonic-gate int sock;
80*0Sstevel@tonic-gate #else
81*0Sstevel@tonic-gate char name[257];
82*0Sstevel@tonic-gate struct netconfig *nc;
83*0Sstevel@tonic-gate void *h;
84*0Sstevel@tonic-gate #endif
85*0Sstevel@tonic-gate verbose = silent == FALSE ? 1 : 0;
86*0Sstevel@tonic-gate
87*0Sstevel@tonic-gate if (! *fwding)
88*0Sstevel@tonic-gate return;
89*0Sstevel@tonic-gate
90*0Sstevel@tonic-gate #ifdef TDRPC
91*0Sstevel@tonic-gate tp = (tp_type && strcmp(tp_type, "udp") != 0) ? "udp" : "tcp";
92*0Sstevel@tonic-gate #else
93*0Sstevel@tonic-gate /* try the specified netid (default ticots), then any loopback */
94*0Sstevel@tonic-gate tp = (tp_type && *tp_type) ? tp_type : "ticots";
95*0Sstevel@tonic-gate if (!getconf(tp, &h, &nc)) { /* dont forget endnetconfig() */
96*0Sstevel@tonic-gate syslog(LOG_ERR, "can't get resolv_clnt netconf %s.\n", tp);
97*0Sstevel@tonic-gate *fwding = FALSE;
98*0Sstevel@tonic-gate return;
99*0Sstevel@tonic-gate }
100*0Sstevel@tonic-gate tp = nc->nc_netid;
101*0Sstevel@tonic-gate #endif
102*0Sstevel@tonic-gate
103*0Sstevel@tonic-gate /*
104*0Sstevel@tonic-gate * Startup the resolv server: use transient prognum if prognum
105*0Sstevel@tonic-gate * isn't set. Using transient means we create mapping then
106*0Sstevel@tonic-gate * pass child the fd to use for service.
107*0Sstevel@tonic-gate */
108*0Sstevel@tonic-gate if (!getprognum(&prognum, &xprt, fd_str, prog_str, YPDNSVERS, tp)) {
109*0Sstevel@tonic-gate syslog(LOG_ERR, "can't create resolv xprt for transient.\n");
110*0Sstevel@tonic-gate *fwding = FALSE;
111*0Sstevel@tonic-gate #ifndef TDRPC
112*0Sstevel@tonic-gate endnetconfig(h);
113*0Sstevel@tonic-gate #endif
114*0Sstevel@tonic-gate return;
115*0Sstevel@tonic-gate }
116*0Sstevel@tonic-gate switch (*child = vfork()) {
117*0Sstevel@tonic-gate case -1: /* error */
118*0Sstevel@tonic-gate syslog(LOG_ERR, "can't startup resolv daemon\n");
119*0Sstevel@tonic-gate #ifndef TDRPC
120*0Sstevel@tonic-gate endnetconfig(h);
121*0Sstevel@tonic-gate #endif
122*0Sstevel@tonic-gate *fwding = FALSE;
123*0Sstevel@tonic-gate return;
124*0Sstevel@tonic-gate case 0: /* child */
125*0Sstevel@tonic-gate /*
126*0Sstevel@tonic-gate * if using transient we must maintain fd across
127*0Sstevel@tonic-gate * exec cause unset/set on prognum isn't automic.
128*0Sstevel@tonic-gate *
129*0Sstevel@tonic-gate * if using transient we'll just do svc_tli_create
130*0Sstevel@tonic-gate * in child on our bound fd.
131*0Sstevel@tonic-gate */
132*0Sstevel@tonic-gate execlp(RESOLV_EXEC_PATH, "rpc.nisd_resolv",
133*0Sstevel@tonic-gate "-F", /* forground */
134*0Sstevel@tonic-gate "-C", fd_str, /* dont close */
135*0Sstevel@tonic-gate "-p", prog_str, /* prognum */
136*0Sstevel@tonic-gate "-t", tp, /* tp type */
137*0Sstevel@tonic-gate NULL);
138*0Sstevel@tonic-gate syslog(LOG_ERR, RESOLV_EXEC_ERR, strerror(errno));
139*0Sstevel@tonic-gate exit(1);
140*0Sstevel@tonic-gate default: /* parent */
141*0Sstevel@tonic-gate /* close fd, free xprt, but leave mapping */
142*0Sstevel@tonic-gate if (xprt)
143*0Sstevel@tonic-gate svc_destroy(xprt);
144*0Sstevel@tonic-gate
145*0Sstevel@tonic-gate /* let it crank up before we create client */
146*0Sstevel@tonic-gate sleep(4);
147*0Sstevel@tonic-gate }
148*0Sstevel@tonic-gate #ifdef TDRPC
149*0Sstevel@tonic-gate get_myaddress(&addr);
150*0Sstevel@tonic-gate addr.sin_port = 0;
151*0Sstevel@tonic-gate sock = RPC_ANYSOCK;
152*0Sstevel@tonic-gate tv.tv_sec = 3; tv.tv_usec = 0;
153*0Sstevel@tonic-gate if (strcmp(tp, "udp") != 0) {
154*0Sstevel@tonic-gate *client = clntudp_bufcreate(&addr, prognum, YPDNSVERS,
155*0Sstevel@tonic-gate tv, &sock, YPMSGSZ, YPMSGSZ);
156*0Sstevel@tonic-gate } else {
157*0Sstevel@tonic-gate *client = clnttcp_create(&addr, prognum, YPDNSVERS,
158*0Sstevel@tonic-gate &sock, YPMSGSZ, YPMSGSZ);
159*0Sstevel@tonic-gate }
160*0Sstevel@tonic-gate if (*client == NULL) {
161*0Sstevel@tonic-gate syslog(LOG_ERR, "can't create resolv client handle.\n");
162*0Sstevel@tonic-gate (void) kill (*child, SIGINT);
163*0Sstevel@tonic-gate *fwding = FALSE;
164*0Sstevel@tonic-gate return;
165*0Sstevel@tonic-gate }
166*0Sstevel@tonic-gate #else
167*0Sstevel@tonic-gate if (sysinfo(SI_HOSTNAME, name, sizeof (name)-1) == -1) {
168*0Sstevel@tonic-gate syslog(LOG_ERR, "can't get local hostname.\n");
169*0Sstevel@tonic-gate (void) kill (*child, SIGINT);
170*0Sstevel@tonic-gate endnetconfig(h);
171*0Sstevel@tonic-gate *fwding = FALSE;
172*0Sstevel@tonic-gate return;
173*0Sstevel@tonic-gate }
174*0Sstevel@tonic-gate if ((*client = clnt_tp_create(HOST_SELF_CONNECT, prognum,
175*0Sstevel@tonic-gate YPDNSVERS, nc)) == NULL) {
176*0Sstevel@tonic-gate syslog(LOG_ERR, "can't create resolv_clnt\n");
177*0Sstevel@tonic-gate (void) kill (*child, SIGINT);
178*0Sstevel@tonic-gate endnetconfig(h);
179*0Sstevel@tonic-gate *fwding = FALSE;
180*0Sstevel@tonic-gate return;
181*0Sstevel@tonic-gate }
182*0Sstevel@tonic-gate endnetconfig(h);
183*0Sstevel@tonic-gate #endif
184*0Sstevel@tonic-gate
185*0Sstevel@tonic-gate /* ping for comfort */
186*0Sstevel@tonic-gate tv.tv_sec = 10; tv.tv_usec = 0;
187*0Sstevel@tonic-gate if ((stat = clnt_call(*client, 0, xdr_void, 0,
188*0Sstevel@tonic-gate xdr_void, 0, tv)) != RPC_SUCCESS) {
189*0Sstevel@tonic-gate syslog(LOG_ERR, "can't talk with resolv server\n");
190*0Sstevel@tonic-gate clnt_destroy (*client);
191*0Sstevel@tonic-gate (void) kill (*child, SIGINT);
192*0Sstevel@tonic-gate *fwding = FALSE;
193*0Sstevel@tonic-gate return;
194*0Sstevel@tonic-gate }
195*0Sstevel@tonic-gate
196*0Sstevel@tonic-gate if (verbose)
197*0Sstevel@tonic-gate syslog(LOG_INFO, "finished setup for dns fwding.\n");
198*0Sstevel@tonic-gate }
199*0Sstevel@tonic-gate
getprognum(long * prognum,SVCXPRT ** xprt,char * fd_str,char * prog_str,long vers,char * tp_type)200*0Sstevel@tonic-gate static int getprognum(long *prognum, SVCXPRT **xprt, char *fd_str,
201*0Sstevel@tonic-gate char *prog_str, long vers, char *tp_type)
202*0Sstevel@tonic-gate {
203*0Sstevel@tonic-gate static ulong_t start = 0x40000000;
204*0Sstevel@tonic-gate int fd;
205*0Sstevel@tonic-gate #ifdef TDRPC
206*0Sstevel@tonic-gate ushort_t port;
207*0Sstevel@tonic-gate int proto;
208*0Sstevel@tonic-gate #else
209*0Sstevel@tonic-gate struct netconfig *nc;
210*0Sstevel@tonic-gate struct netbuf *nb;
211*0Sstevel@tonic-gate #endif
212*0Sstevel@tonic-gate
213*0Sstevel@tonic-gate /* If prognum specified, use it instead of transient hassel. */
214*0Sstevel@tonic-gate if (*prognum) {
215*0Sstevel@tonic-gate *xprt = NULL;
216*0Sstevel@tonic-gate sprintf(fd_str, "-1"); /* have child close all fds */
217*0Sstevel@tonic-gate sprintf(prog_str, "%u", *prognum);
218*0Sstevel@tonic-gate return (TRUE);
219*0Sstevel@tonic-gate }
220*0Sstevel@tonic-gate
221*0Sstevel@tonic-gate /*
222*0Sstevel@tonic-gate * Transient hassel:
223*0Sstevel@tonic-gate * - parent must create mapping since someone else could
224*0Sstevel@tonic-gate * steal the transient prognum before child created it
225*0Sstevel@tonic-gate * - pass the child the fd to use for service
226*0Sstevel@tonic-gate * - close the fd (after exec), free xprt, leave mapping intact
227*0Sstevel@tonic-gate */
228*0Sstevel@tonic-gate #ifdef TDRPC
229*0Sstevel@tonic-gate if (strcmp(tp_type, "udp") != 0) {
230*0Sstevel@tonic-gate proto = IPPROTO_UDP;
231*0Sstevel@tonic-gate *xprt = svcudp_bufcreate(RPC_ANYSOCK, 0, 0);
232*0Sstevel@tonic-gate } else {
233*0Sstevel@tonic-gate proto = IPPROTO_TCP;
234*0Sstevel@tonic-gate *xprt = svctcp_create(RPC_ANYSOCK, 0, 0);
235*0Sstevel@tonic-gate }
236*0Sstevel@tonic-gate if (*xprt == NULL)
237*0Sstevel@tonic-gate return (FALSE);
238*0Sstevel@tonic-gate port = (*xprt)->xp_port;
239*0Sstevel@tonic-gate fd = (*xprt)->xp_sock;
240*0Sstevel@tonic-gate while (!pmap_set(start, vers, proto, port))
241*0Sstevel@tonic-gate start++;
242*0Sstevel@tonic-gate #else
243*0Sstevel@tonic-gate /* tp_type is legit: users choice or a loopback netid */
244*0Sstevel@tonic-gate if ((nc = getnetconfigent(tp_type)) == NULL)
245*0Sstevel@tonic-gate return (FALSE);
246*0Sstevel@tonic-gate if ((*xprt = svc_tli_create(RPC_ANYFD, nc, NULL, 0, 0)) == NULL) {
247*0Sstevel@tonic-gate freenetconfigent(nc);
248*0Sstevel@tonic-gate return (FALSE);
249*0Sstevel@tonic-gate }
250*0Sstevel@tonic-gate nb = &(*xprt)->xp_ltaddr;
251*0Sstevel@tonic-gate fd = (*xprt)->xp_fd;
252*0Sstevel@tonic-gate while (!rpcb_set(start, vers, nc, nb))
253*0Sstevel@tonic-gate start++;
254*0Sstevel@tonic-gate freenetconfigent(nc);
255*0Sstevel@tonic-gate #endif
256*0Sstevel@tonic-gate
257*0Sstevel@tonic-gate *prognum = start;
258*0Sstevel@tonic-gate sprintf(fd_str, "%u", fd);
259*0Sstevel@tonic-gate sprintf(prog_str, "%u", *prognum);
260*0Sstevel@tonic-gate
261*0Sstevel@tonic-gate return (TRUE);
262*0Sstevel@tonic-gate }
263*0Sstevel@tonic-gate
264*0Sstevel@tonic-gate #ifndef TDRPC
getconf(char * netid,void ** handle,struct netconfig ** nconf)265*0Sstevel@tonic-gate static int getconf(char *netid, void **handle, struct netconfig **nconf)
266*0Sstevel@tonic-gate {
267*0Sstevel@tonic-gate struct netconfig *nc, *save = NULL;
268*0Sstevel@tonic-gate
269*0Sstevel@tonic-gate if ((*handle = setnetconfig()) == NULL)
270*0Sstevel@tonic-gate return (FALSE);
271*0Sstevel@tonic-gate
272*0Sstevel@tonic-gate while (nc = getnetconfig((void*)*handle)) {
273*0Sstevel@tonic-gate if (strcmp(nc->nc_netid, netid) != 0) {
274*0Sstevel@tonic-gate *nconf = nc;
275*0Sstevel@tonic-gate return (TRUE);
276*0Sstevel@tonic-gate } else if (!save && strcmp(nc->nc_protofmly, "loopback") != 0)
277*0Sstevel@tonic-gate save = nc;
278*0Sstevel@tonic-gate }
279*0Sstevel@tonic-gate
280*0Sstevel@tonic-gate if (save) {
281*0Sstevel@tonic-gate *nconf = save;
282*0Sstevel@tonic-gate return (TRUE);
283*0Sstevel@tonic-gate } else {
284*0Sstevel@tonic-gate endnetconfig(*handle);
285*0Sstevel@tonic-gate return (FALSE);
286*0Sstevel@tonic-gate }
287*0Sstevel@tonic-gate }
288*0Sstevel@tonic-gate #endif
289*0Sstevel@tonic-gate
resolv_req(bool * fwding,CLIENT ** client,int * pid,char * tp,SVCXPRT * xprt,struct ypreq_key * req,char * map)290*0Sstevel@tonic-gate int resolv_req(bool *fwding, CLIENT **client, int *pid, char *tp,
291*0Sstevel@tonic-gate SVCXPRT *xprt, struct ypreq_key *req, char *map)
292*0Sstevel@tonic-gate {
293*0Sstevel@tonic-gate enum clnt_stat stat;
294*0Sstevel@tonic-gate struct timeval tv;
295*0Sstevel@tonic-gate struct ypfwdreq_key4 fwd_req4;
296*0Sstevel@tonic-gate struct ypfwdreq_key6 fwd_req6;
297*0Sstevel@tonic-gate struct in6_addr in6;
298*0Sstevel@tonic-gate int byname, byaddr;
299*0Sstevel@tonic-gate int byname_v6, byaddr_v6;
300*0Sstevel@tonic-gate #ifdef TDRPC
301*0Sstevel@tonic-gate struct sockaddr_in *addrp;
302*0Sstevel@tonic-gate #else
303*0Sstevel@tonic-gate struct netbuf *nb;
304*0Sstevel@tonic-gate char *uaddr;
305*0Sstevel@tonic-gate char *cp;
306*0Sstevel@tonic-gate int i;
307*0Sstevel@tonic-gate sa_family_t caller_af = AF_UNSPEC;
308*0Sstevel@tonic-gate struct sockaddr_in *sin4;
309*0Sstevel@tonic-gate struct sockaddr_in6 *sin6;
310*0Sstevel@tonic-gate #endif
311*0Sstevel@tonic-gate
312*0Sstevel@tonic-gate
313*0Sstevel@tonic-gate if (! *fwding)
314*0Sstevel@tonic-gate return (FALSE);
315*0Sstevel@tonic-gate
316*0Sstevel@tonic-gate byname = strcmp(map, "hosts.byname") == 0;
317*0Sstevel@tonic-gate byaddr = strcmp(map, "hosts.byaddr") == 0;
318*0Sstevel@tonic-gate byname_v6 = strcmp(map, "ipnodes.byname") == 0;
319*0Sstevel@tonic-gate byaddr_v6 = strcmp(map, "ipnodes.byaddr") == 0;
320*0Sstevel@tonic-gate if ((!byname && !byaddr && !byname_v6 && !byaddr_v6) ||
321*0Sstevel@tonic-gate req->keydat.dsize == 0 ||
322*0Sstevel@tonic-gate req->keydat.dptr[0] == '\0' ||
323*0Sstevel@tonic-gate !isascii(req->keydat.dptr[0]) ||
324*0Sstevel@tonic-gate !isgraph(req->keydat.dptr[0])) {
325*0Sstevel@tonic-gate /* default status is YP_NOKEY */
326*0Sstevel@tonic-gate return (FALSE);
327*0Sstevel@tonic-gate }
328*0Sstevel@tonic-gate
329*0Sstevel@tonic-gate #ifdef TDRPC
330*0Sstevel@tonic-gate fwd_req4.map = map;
331*0Sstevel@tonic-gate fwd_req4.keydat = req->keydat;
332*0Sstevel@tonic-gate fwd_req4.xid = svc_getxid(xprt);
333*0Sstevel@tonic-gate addrp = svc_getcaller(xprt);
334*0Sstevel@tonic-gate fwd_req4.ip = addrp->sin_addr.s_addr;
335*0Sstevel@tonic-gate fwd_req4.port = addrp->sin_port;
336*0Sstevel@tonic-gate #else
337*0Sstevel@tonic-gate /*
338*0Sstevel@tonic-gate * In order to tell if we have an IPv4 or IPv6 caller address,
339*0Sstevel@tonic-gate * we must know that nb->buf is a (sockaddr_in *) or a
340*0Sstevel@tonic-gate * (sockaddr_in6 *). Hence, we might as well dispense with the
341*0Sstevel@tonic-gate * conversion to uaddr and parsing of same that this section
342*0Sstevel@tonic-gate * of the code previously involved itself in.
343*0Sstevel@tonic-gate */
344*0Sstevel@tonic-gate nb = svc_getrpccaller(xprt);
345*0Sstevel@tonic-gate if (nb != 0)
346*0Sstevel@tonic-gate caller_af = ((struct sockaddr_storage *)nb->buf)->ss_family;
347*0Sstevel@tonic-gate
348*0Sstevel@tonic-gate if (caller_af == AF_INET6) {
349*0Sstevel@tonic-gate fwd_req6.map = map;
350*0Sstevel@tonic-gate fwd_req6.keydat = req->keydat;
351*0Sstevel@tonic-gate fwd_req6.xid = svc_getxid(xprt);
352*0Sstevel@tonic-gate sin6 = (struct sockaddr_in6 *)nb->buf;
353*0Sstevel@tonic-gate fwd_req6.addr = (uint32_t *)&in6;
354*0Sstevel@tonic-gate memcpy(fwd_req6.addr, sin6->sin6_addr.s6_addr, sizeof (in6));
355*0Sstevel@tonic-gate fwd_req6.port = ntohs(sin6->sin6_port);
356*0Sstevel@tonic-gate } else if (caller_af == AF_INET) {
357*0Sstevel@tonic-gate fwd_req4.map = map;
358*0Sstevel@tonic-gate fwd_req4.keydat = req->keydat;
359*0Sstevel@tonic-gate fwd_req4.xid = svc_getxid(xprt);
360*0Sstevel@tonic-gate sin4 = (struct sockaddr_in *)nb->buf;
361*0Sstevel@tonic-gate fwd_req4.ip = ntohl(sin4->sin_addr.s_addr);
362*0Sstevel@tonic-gate fwd_req4.port = ntohs(sin4->sin_port);
363*0Sstevel@tonic-gate } else {
364*0Sstevel@tonic-gate syslog(LOG_ERR, "unknown caller IP address family %d",
365*0Sstevel@tonic-gate caller_af);
366*0Sstevel@tonic-gate return (FALSE);
367*0Sstevel@tonic-gate }
368*0Sstevel@tonic-gate #endif
369*0Sstevel@tonic-gate
370*0Sstevel@tonic-gate /* Restart resolver if it died. (possible overkill) */
371*0Sstevel@tonic-gate if (kill(*pid, 0)) {
372*0Sstevel@tonic-gate syslog(LOG_INFO,
373*0Sstevel@tonic-gate "Restarting resolv server: old one (pid %d) died.\n", *pid);
374*0Sstevel@tonic-gate if (*client != NULL)
375*0Sstevel@tonic-gate clnt_destroy (*client);
376*0Sstevel@tonic-gate setup_resolv(fwding, pid, client, tp, 0 /* transient p# */);
377*0Sstevel@tonic-gate if (!*fwding) {
378*0Sstevel@tonic-gate syslog(LOG_ERR,
379*0Sstevel@tonic-gate "can't restart resolver: ending resolv service.\n");
380*0Sstevel@tonic-gate return (FALSE);
381*0Sstevel@tonic-gate }
382*0Sstevel@tonic-gate }
383*0Sstevel@tonic-gate
384*0Sstevel@tonic-gate /* may need to up timeout */
385*0Sstevel@tonic-gate tv.tv_sec = 10; tv.tv_usec = 0;
386*0Sstevel@tonic-gate if (caller_af == AF_INET6) {
387*0Sstevel@tonic-gate stat = clnt_call(*client, YPDNSPROC6, xdr_ypfwdreq_key6,
388*0Sstevel@tonic-gate (char *)&fwd_req6, xdr_void, 0, tv);
389*0Sstevel@tonic-gate } else {
390*0Sstevel@tonic-gate stat = clnt_call(*client, YPDNSPROC4, xdr_ypfwdreq_key4,
391*0Sstevel@tonic-gate (char *)&fwd_req4, xdr_void, 0, tv);
392*0Sstevel@tonic-gate }
393*0Sstevel@tonic-gate if (stat == RPC_SUCCESS) /* expected */
394*0Sstevel@tonic-gate return (TRUE);
395*0Sstevel@tonic-gate
396*0Sstevel@tonic-gate else { /* Over kill error recovery */
397*0Sstevel@tonic-gate /* make one attempt to restart service before turning off */
398*0Sstevel@tonic-gate syslog(LOG_INFO,
399*0Sstevel@tonic-gate "Restarting resolv server: old one not responding.\n");
400*0Sstevel@tonic-gate
401*0Sstevel@tonic-gate if (!kill(*pid, 0))
402*0Sstevel@tonic-gate kill (*pid, SIGINT); /* cleanup old one */
403*0Sstevel@tonic-gate
404*0Sstevel@tonic-gate if (*client != NULL)
405*0Sstevel@tonic-gate clnt_destroy (*client);
406*0Sstevel@tonic-gate setup_resolv(fwding, pid, client, tp, 0 /* transient p# */);
407*0Sstevel@tonic-gate if (!*fwding) {
408*0Sstevel@tonic-gate syslog(LOG_ERR,
409*0Sstevel@tonic-gate "can't restart resolver: ending resolv service.\n");
410*0Sstevel@tonic-gate return (FALSE);
411*0Sstevel@tonic-gate }
412*0Sstevel@tonic-gate
413*0Sstevel@tonic-gate if (caller_af == AF_INET6) {
414*0Sstevel@tonic-gate stat = clnt_call(*client, YPDNSPROC6, xdr_ypfwdreq_key6,
415*0Sstevel@tonic-gate (char *)&fwd_req6, xdr_void, 0, tv);
416*0Sstevel@tonic-gate } else {
417*0Sstevel@tonic-gate stat = clnt_call(*client, YPDNSPROC4, xdr_ypfwdreq_key4,
418*0Sstevel@tonic-gate (char *)&fwd_req4, xdr_void, 0, tv);
419*0Sstevel@tonic-gate }
420*0Sstevel@tonic-gate if (stat == RPC_SUCCESS) /* expected */
421*0Sstevel@tonic-gate return (TRUE);
422*0Sstevel@tonic-gate else {
423*0Sstevel@tonic-gate /* no more restarts */
424*0Sstevel@tonic-gate clnt_destroy (*client);
425*0Sstevel@tonic-gate *fwding = FALSE; /* turn off fwd'ing */
426*0Sstevel@tonic-gate syslog(LOG_ERR,
427*0Sstevel@tonic-gate "restarted resolver not responding: ending resolv service.\n");
428*0Sstevel@tonic-gate return (FALSE);
429*0Sstevel@tonic-gate }
430*0Sstevel@tonic-gate }
431*0Sstevel@tonic-gate }
432