1*7c478bd9Sstevel@tonic-gate /* 2*7c478bd9Sstevel@tonic-gate * CDDL HEADER START 3*7c478bd9Sstevel@tonic-gate * 4*7c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*7c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 6*7c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 7*7c478bd9Sstevel@tonic-gate * with the License. 8*7c478bd9Sstevel@tonic-gate * 9*7c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*7c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 11*7c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 12*7c478bd9Sstevel@tonic-gate * and limitations under the License. 13*7c478bd9Sstevel@tonic-gate * 14*7c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 15*7c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*7c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 17*7c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 18*7c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 19*7c478bd9Sstevel@tonic-gate * 20*7c478bd9Sstevel@tonic-gate * CDDL HEADER END 21*7c478bd9Sstevel@tonic-gate */ 22*7c478bd9Sstevel@tonic-gate /* 23*7c478bd9Sstevel@tonic-gate * Copyright 1999 Sun Microsystems, Inc. All rights reserved. 24*7c478bd9Sstevel@tonic-gate * Use is subject to license terms. 25*7c478bd9Sstevel@tonic-gate */ 26*7c478bd9Sstevel@tonic-gate 27*7c478bd9Sstevel@tonic-gate /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 28*7c478bd9Sstevel@tonic-gate /* All Rights Reserved */ 29*7c478bd9Sstevel@tonic-gate 30*7c478bd9Sstevel@tonic-gate /* 31*7c478bd9Sstevel@tonic-gate * University Copyright- Copyright (c) 1982, 1986, 1988 32*7c478bd9Sstevel@tonic-gate * The Regents of the University of California 33*7c478bd9Sstevel@tonic-gate * All Rights Reserved 34*7c478bd9Sstevel@tonic-gate * 35*7c478bd9Sstevel@tonic-gate * University Acknowledgment- Portions of this document are derived from 36*7c478bd9Sstevel@tonic-gate * software developed by the University of California, Berkeley, and its 37*7c478bd9Sstevel@tonic-gate * contributors. 38*7c478bd9Sstevel@tonic-gate */ 39*7c478bd9Sstevel@tonic-gate 40*7c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 41*7c478bd9Sstevel@tonic-gate 42*7c478bd9Sstevel@tonic-gate #include "synonyms.h" 43*7c478bd9Sstevel@tonic-gate 44*7c478bd9Sstevel@tonic-gate #include <sys/types.h> 45*7c478bd9Sstevel@tonic-gate #include <sys/sockio.h> 46*7c478bd9Sstevel@tonic-gate #include <sys/socket.h> 47*7c478bd9Sstevel@tonic-gate #include <netinet/in.h> 48*7c478bd9Sstevel@tonic-gate #include <stdio.h> 49*7c478bd9Sstevel@tonic-gate #include <arpa/nameser.h> 50*7c478bd9Sstevel@tonic-gate #include <resolv.h> 51*7c478bd9Sstevel@tonic-gate 52*7c478bd9Sstevel@tonic-gate #include <netinet/in.h> 53*7c478bd9Sstevel@tonic-gate #include <net/if.h> 54*7c478bd9Sstevel@tonic-gate #include <netinet/if_ether.h> 55*7c478bd9Sstevel@tonic-gate #include <arpa/inet.h> 56*7c478bd9Sstevel@tonic-gate 57*7c478bd9Sstevel@tonic-gate #define MAXIFS 256 58*7c478bd9Sstevel@tonic-gate 59*7c478bd9Sstevel@tonic-gate /* 60*7c478bd9Sstevel@tonic-gate * Resolver state default settings 61*7c478bd9Sstevel@tonic-gate */ 62*7c478bd9Sstevel@tonic-gate 63*7c478bd9Sstevel@tonic-gate struct state _res = { 64*7c478bd9Sstevel@tonic-gate RES_TIMEOUT, /* retransmition time interval */ 65*7c478bd9Sstevel@tonic-gate 4, /* number of times to retransmit */ 66*7c478bd9Sstevel@tonic-gate RES_DEFAULT, /* options flags */ 67*7c478bd9Sstevel@tonic-gate 1, /* number of name servers */ 68*7c478bd9Sstevel@tonic-gate }; 69*7c478bd9Sstevel@tonic-gate 70*7c478bd9Sstevel@tonic-gate /* 71*7c478bd9Sstevel@tonic-gate * Set up default settings. If the configuration file exist, the values 72*7c478bd9Sstevel@tonic-gate * there will have precedence. Otherwise, the server address is set to 73*7c478bd9Sstevel@tonic-gate * INADDR_LOOPBACK and the default domain name comes from the gethostname(). 74*7c478bd9Sstevel@tonic-gate * BUT if the NIS/RPC domain name is set, that is used if all else fails. 75*7c478bd9Sstevel@tonic-gate * 76*7c478bd9Sstevel@tonic-gate * The configuration file should only be used if you want to redefine your 77*7c478bd9Sstevel@tonic-gate * domain or run without a server on your machine. 78*7c478bd9Sstevel@tonic-gate * 79*7c478bd9Sstevel@tonic-gate * Note the user can always override then domain name with the environment 80*7c478bd9Sstevel@tonic-gate * variable LOCALDOMAIN which has absolute priority. 81*7c478bd9Sstevel@tonic-gate * 82*7c478bd9Sstevel@tonic-gate * 83*7c478bd9Sstevel@tonic-gate * Return 0 if completes successfully, -1 on error 84*7c478bd9Sstevel@tonic-gate */ 85*7c478bd9Sstevel@tonic-gate res_init() 86*7c478bd9Sstevel@tonic-gate { 87*7c478bd9Sstevel@tonic-gate register FILE *fp; 88*7c478bd9Sstevel@tonic-gate register char *cp, **pp; 89*7c478bd9Sstevel@tonic-gate register int n; 90*7c478bd9Sstevel@tonic-gate char buf[BUFSIZ]; 91*7c478bd9Sstevel@tonic-gate #ifdef SYSV 92*7c478bd9Sstevel@tonic-gate extern char *strchr(); 93*7c478bd9Sstevel@tonic-gate #else 94*7c478bd9Sstevel@tonic-gate extern char *index(); 95*7c478bd9Sstevel@tonic-gate #endif 96*7c478bd9Sstevel@tonic-gate extern char *strcpy(), *strncpy(); 97*7c478bd9Sstevel@tonic-gate extern char *getenv(); 98*7c478bd9Sstevel@tonic-gate int nserv = 0; /* number of nameserver records read from file */ 99*7c478bd9Sstevel@tonic-gate int haveenv = 0; 100*7c478bd9Sstevel@tonic-gate int havesearch = 0; 101*7c478bd9Sstevel@tonic-gate 102*7c478bd9Sstevel@tonic-gate _res.nsaddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK); /* INADDR_ANY */ 103*7c478bd9Sstevel@tonic-gate _res.nsaddr.sin_family = AF_INET; 104*7c478bd9Sstevel@tonic-gate _res.nsaddr.sin_port = htons(NAMESERVER_PORT); 105*7c478bd9Sstevel@tonic-gate _res.nscount = 1; 106*7c478bd9Sstevel@tonic-gate 107*7c478bd9Sstevel@tonic-gate #ifdef SIOCGIFNUM 108*7c478bd9Sstevel@tonic-gate { int numifs, s, n, int_up; 109*7c478bd9Sstevel@tonic-gate struct ifconf ifc; 110*7c478bd9Sstevel@tonic-gate register struct ifreq *ifrp; 111*7c478bd9Sstevel@tonic-gate struct ifreq ifr; 112*7c478bd9Sstevel@tonic-gate unsigned bufsize; 113*7c478bd9Sstevel@tonic-gate unsigned int flags; 114*7c478bd9Sstevel@tonic-gate char *buf; 115*7c478bd9Sstevel@tonic-gate extern void *malloc(); 116*7c478bd9Sstevel@tonic-gate 117*7c478bd9Sstevel@tonic-gate if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { 118*7c478bd9Sstevel@tonic-gate perror("socket"); 119*7c478bd9Sstevel@tonic-gate return (-1); 120*7c478bd9Sstevel@tonic-gate } 121*7c478bd9Sstevel@tonic-gate if (ioctl(s, SIOCGIFNUM, (char *)&numifs) < 0) { 122*7c478bd9Sstevel@tonic-gate numifs = MAXIFS; 123*7c478bd9Sstevel@tonic-gate } 124*7c478bd9Sstevel@tonic-gate bufsize = numifs * sizeof (struct ifreq); 125*7c478bd9Sstevel@tonic-gate buf = (char *)malloc(bufsize); 126*7c478bd9Sstevel@tonic-gate if (buf == NULL) { 127*7c478bd9Sstevel@tonic-gate perror("out of memory"); 128*7c478bd9Sstevel@tonic-gate close(s); 129*7c478bd9Sstevel@tonic-gate return (-1); 130*7c478bd9Sstevel@tonic-gate } 131*7c478bd9Sstevel@tonic-gate ifc.ifc_len = bufsize; 132*7c478bd9Sstevel@tonic-gate ifc.ifc_buf = buf; 133*7c478bd9Sstevel@tonic-gate if (ioctl(s, SIOCGIFCONF, (char *)&ifc) < 0) { 134*7c478bd9Sstevel@tonic-gate perror("ifconfig: SIOCGIFCONF"); 135*7c478bd9Sstevel@tonic-gate close(s); 136*7c478bd9Sstevel@tonic-gate free(buf); 137*7c478bd9Sstevel@tonic-gate return (-1); 138*7c478bd9Sstevel@tonic-gate } 139*7c478bd9Sstevel@tonic-gate 140*7c478bd9Sstevel@tonic-gate int_up = 0; 141*7c478bd9Sstevel@tonic-gate ifrp = ifc.ifc_req; 142*7c478bd9Sstevel@tonic-gate for (n = ifc.ifc_len / sizeof (struct ifreq); n > 0; 143*7c478bd9Sstevel@tonic-gate n--, ifrp++) { 144*7c478bd9Sstevel@tonic-gate memset((void *) &ifr, 0, sizeof (ifr)); 145*7c478bd9Sstevel@tonic-gate strncpy(ifr.ifr_name, ifrp->ifr_name, 146*7c478bd9Sstevel@tonic-gate sizeof (ifr.ifr_name)); 147*7c478bd9Sstevel@tonic-gate if (ioctl(s, SIOCGIFFLAGS, (char *)&ifr) < 0) { 148*7c478bd9Sstevel@tonic-gate perror("SIOCGIFFLAGS"); 149*7c478bd9Sstevel@tonic-gate close(s); 150*7c478bd9Sstevel@tonic-gate free(buf); 151*7c478bd9Sstevel@tonic-gate return (-1); 152*7c478bd9Sstevel@tonic-gate } 153*7c478bd9Sstevel@tonic-gate flags = ifr.ifr_flags; 154*7c478bd9Sstevel@tonic-gate /* we are looking for a non-loopback interface */ 155*7c478bd9Sstevel@tonic-gate if ((flags & IFF_UP) && ((flags & IFF_LOOPBACK) == 0)) 156*7c478bd9Sstevel@tonic-gate int_up = 1; 157*7c478bd9Sstevel@tonic-gate } 158*7c478bd9Sstevel@tonic-gate close(s); 159*7c478bd9Sstevel@tonic-gate free(buf); 160*7c478bd9Sstevel@tonic-gate if (int_up == 0) /* all the non-LOOPBACK interfaces are DOWN */ 161*7c478bd9Sstevel@tonic-gate return (-1); 162*7c478bd9Sstevel@tonic-gate } 163*7c478bd9Sstevel@tonic-gate #endif /* SIOCGIFNUM */ 164*7c478bd9Sstevel@tonic-gate 165*7c478bd9Sstevel@tonic-gate 166*7c478bd9Sstevel@tonic-gate /* 167*7c478bd9Sstevel@tonic-gate * for the benefit of hidden NIS domains, we use the same procedure 168*7c478bd9Sstevel@tonic-gate * as sendmail: convert leading + to dot, then drop to first dot 169*7c478bd9Sstevel@tonic-gate */ 170*7c478bd9Sstevel@tonic-gate getdomainname(buf, BUFSIZ); 171*7c478bd9Sstevel@tonic-gate if (buf[0] == '+') 172*7c478bd9Sstevel@tonic-gate buf[0] = '.'; 173*7c478bd9Sstevel@tonic-gate #ifdef SYSV 174*7c478bd9Sstevel@tonic-gate cp = strchr(buf, (int)'.'); 175*7c478bd9Sstevel@tonic-gate #else 176*7c478bd9Sstevel@tonic-gate cp = index(buf, '.'); 177*7c478bd9Sstevel@tonic-gate #endif 178*7c478bd9Sstevel@tonic-gate if (cp == NULL) 179*7c478bd9Sstevel@tonic-gate strcpy(_res.defdname, buf); 180*7c478bd9Sstevel@tonic-gate else 181*7c478bd9Sstevel@tonic-gate strcpy(_res.defdname, cp+1); 182*7c478bd9Sstevel@tonic-gate 183*7c478bd9Sstevel@tonic-gate /* Allow user to override the local domain definition */ 184*7c478bd9Sstevel@tonic-gate if ((cp = getenv("LOCALDOMAIN")) != NULL) { 185*7c478bd9Sstevel@tonic-gate (void) strncpy(_res.defdname, cp, sizeof (_res.defdname)); 186*7c478bd9Sstevel@tonic-gate haveenv++; 187*7c478bd9Sstevel@tonic-gate } 188*7c478bd9Sstevel@tonic-gate 189*7c478bd9Sstevel@tonic-gate if ((fp = fopen(_PATH_RESCONF, "r")) != NULL) { 190*7c478bd9Sstevel@tonic-gate /* read the config file */ 191*7c478bd9Sstevel@tonic-gate while (fgets(buf, sizeof (buf), fp) != NULL) { 192*7c478bd9Sstevel@tonic-gate /* read default domain name */ 193*7c478bd9Sstevel@tonic-gate if (!strncmp(buf, "domain", sizeof ("domain") - 1)) { 194*7c478bd9Sstevel@tonic-gate if (haveenv) /* skip if have from environ */ 195*7c478bd9Sstevel@tonic-gate continue; 196*7c478bd9Sstevel@tonic-gate cp = buf + sizeof ("domain") - 1; 197*7c478bd9Sstevel@tonic-gate while (*cp == ' ' || *cp == '\t') 198*7c478bd9Sstevel@tonic-gate cp++; 199*7c478bd9Sstevel@tonic-gate if ((*cp == '\0') || (*cp == '\n')) 200*7c478bd9Sstevel@tonic-gate continue; 201*7c478bd9Sstevel@tonic-gate (void) strncpy(_res.defdname, cp, sizeof (_res.defdname) - 1); 202*7c478bd9Sstevel@tonic-gate #ifdef SYSV 203*7c478bd9Sstevel@tonic-gate if ((cp = strchr(_res.defdname, (int)'\n')) != NULL) 204*7c478bd9Sstevel@tonic-gate #else 205*7c478bd9Sstevel@tonic-gate if ((cp = index(_res.defdname, '\n')) != NULL) 206*7c478bd9Sstevel@tonic-gate #endif 207*7c478bd9Sstevel@tonic-gate *cp = '\0'; 208*7c478bd9Sstevel@tonic-gate havesearch = 0; 209*7c478bd9Sstevel@tonic-gate continue; 210*7c478bd9Sstevel@tonic-gate } 211*7c478bd9Sstevel@tonic-gate /* set search list */ 212*7c478bd9Sstevel@tonic-gate if (!strncmp(buf, "search", sizeof ("search") - 1)) { 213*7c478bd9Sstevel@tonic-gate if (haveenv) /* skip if have from environ */ 214*7c478bd9Sstevel@tonic-gate continue; 215*7c478bd9Sstevel@tonic-gate cp = buf + sizeof ("search") - 1; 216*7c478bd9Sstevel@tonic-gate while (*cp == ' ' || *cp == '\t') 217*7c478bd9Sstevel@tonic-gate cp++; 218*7c478bd9Sstevel@tonic-gate if ((*cp == '\0') || (*cp == '\n')) 219*7c478bd9Sstevel@tonic-gate continue; 220*7c478bd9Sstevel@tonic-gate (void) strncpy(_res.defdname, cp, sizeof (_res.defdname) - 1); 221*7c478bd9Sstevel@tonic-gate #ifdef SYSV 222*7c478bd9Sstevel@tonic-gate if ((cp = strchr(_res.defdname, (int)'\n')) != NULL) 223*7c478bd9Sstevel@tonic-gate #else 224*7c478bd9Sstevel@tonic-gate if ((cp = index(_res.defdname, '\n')) != NULL) 225*7c478bd9Sstevel@tonic-gate #endif 226*7c478bd9Sstevel@tonic-gate *cp = '\0'; 227*7c478bd9Sstevel@tonic-gate /* 228*7c478bd9Sstevel@tonic-gate * Set search list to be blank-separated strings 229*7c478bd9Sstevel@tonic-gate * on rest of line. 230*7c478bd9Sstevel@tonic-gate */ 231*7c478bd9Sstevel@tonic-gate cp = _res.defdname; 232*7c478bd9Sstevel@tonic-gate pp = _res.dnsrch; 233*7c478bd9Sstevel@tonic-gate *pp++ = cp; 234*7c478bd9Sstevel@tonic-gate for (n = 0; *cp && pp < _res.dnsrch + MAXDNSRCH; cp++) { 235*7c478bd9Sstevel@tonic-gate if (*cp == ' ' || *cp == '\t') { 236*7c478bd9Sstevel@tonic-gate *cp = 0; 237*7c478bd9Sstevel@tonic-gate n = 1; 238*7c478bd9Sstevel@tonic-gate } else if (n) { 239*7c478bd9Sstevel@tonic-gate *pp++ = cp; 240*7c478bd9Sstevel@tonic-gate n = 0; 241*7c478bd9Sstevel@tonic-gate } 242*7c478bd9Sstevel@tonic-gate } 243*7c478bd9Sstevel@tonic-gate /* null terminate last domain if there are excess */ 244*7c478bd9Sstevel@tonic-gate while (*cp != '\0' && *cp != ' ' && *cp != '\t') 245*7c478bd9Sstevel@tonic-gate cp++; 246*7c478bd9Sstevel@tonic-gate *cp = '\0'; 247*7c478bd9Sstevel@tonic-gate *pp++ = 0; 248*7c478bd9Sstevel@tonic-gate havesearch = 1; 249*7c478bd9Sstevel@tonic-gate continue; 250*7c478bd9Sstevel@tonic-gate } 251*7c478bd9Sstevel@tonic-gate /* read nameservers to query */ 252*7c478bd9Sstevel@tonic-gate if (!strncmp(buf, "nameserver", sizeof ("nameserver") - 1) && 253*7c478bd9Sstevel@tonic-gate (nserv < MAXNS)) { 254*7c478bd9Sstevel@tonic-gate cp = buf + sizeof ("nameserver") - 1; 255*7c478bd9Sstevel@tonic-gate while (*cp == ' ' || *cp == '\t') 256*7c478bd9Sstevel@tonic-gate cp++; 257*7c478bd9Sstevel@tonic-gate if ((*cp == '\0') || (*cp == '\n')) 258*7c478bd9Sstevel@tonic-gate continue; 259*7c478bd9Sstevel@tonic-gate if ((_res.nsaddr_list[nserv].sin_addr.s_addr = 260*7c478bd9Sstevel@tonic-gate inet_addr(cp)) == (unsigned) -1) { 261*7c478bd9Sstevel@tonic-gate _res.nsaddr_list[n].sin_addr.s_addr = INADDR_ANY; 262*7c478bd9Sstevel@tonic-gate continue; 263*7c478bd9Sstevel@tonic-gate } 264*7c478bd9Sstevel@tonic-gate _res.nsaddr_list[nserv].sin_family = AF_INET; 265*7c478bd9Sstevel@tonic-gate _res.nsaddr_list[nserv].sin_port = htons(NAMESERVER_PORT); 266*7c478bd9Sstevel@tonic-gate nserv++; 267*7c478bd9Sstevel@tonic-gate continue; 268*7c478bd9Sstevel@tonic-gate } 269*7c478bd9Sstevel@tonic-gate } 270*7c478bd9Sstevel@tonic-gate if (nserv > 1) 271*7c478bd9Sstevel@tonic-gate _res.nscount = nserv; 272*7c478bd9Sstevel@tonic-gate (void) fclose(fp); 273*7c478bd9Sstevel@tonic-gate } 274*7c478bd9Sstevel@tonic-gate if (_res.defdname[0] == 0) { 275*7c478bd9Sstevel@tonic-gate if (gethostname(buf, sizeof (_res.defdname)) == 0 && 276*7c478bd9Sstevel@tonic-gate #ifdef SYSV 277*7c478bd9Sstevel@tonic-gate (cp = strchr(buf, (int)'.'))) 278*7c478bd9Sstevel@tonic-gate #else 279*7c478bd9Sstevel@tonic-gate (cp = index(buf, '.'))) 280*7c478bd9Sstevel@tonic-gate #endif 281*7c478bd9Sstevel@tonic-gate (void) strcpy(_res.defdname, cp + 1); 282*7c478bd9Sstevel@tonic-gate } 283*7c478bd9Sstevel@tonic-gate 284*7c478bd9Sstevel@tonic-gate /* find components of local domain that might be searched */ 285*7c478bd9Sstevel@tonic-gate if (havesearch == 0) { 286*7c478bd9Sstevel@tonic-gate pp = _res.dnsrch; 287*7c478bd9Sstevel@tonic-gate *pp++ = _res.defdname; 288*7c478bd9Sstevel@tonic-gate for (cp = _res.defdname, n = 0; *cp; cp++) 289*7c478bd9Sstevel@tonic-gate if (*cp == '.') 290*7c478bd9Sstevel@tonic-gate n++; 291*7c478bd9Sstevel@tonic-gate cp = _res.defdname; 292*7c478bd9Sstevel@tonic-gate for (; n >= LOCALDOMAINPARTS && pp < _res.dnsrch + MAXDFLSRCH; n--) { 293*7c478bd9Sstevel@tonic-gate #ifdef SYSV 294*7c478bd9Sstevel@tonic-gate cp = strchr(cp, (int)'.'); 295*7c478bd9Sstevel@tonic-gate #else 296*7c478bd9Sstevel@tonic-gate cp = index(cp, '.'); 297*7c478bd9Sstevel@tonic-gate #endif 298*7c478bd9Sstevel@tonic-gate *pp++ = ++cp; 299*7c478bd9Sstevel@tonic-gate } 300*7c478bd9Sstevel@tonic-gate *pp++ = 0; 301*7c478bd9Sstevel@tonic-gate } 302*7c478bd9Sstevel@tonic-gate _res.options |= RES_INIT; 303*7c478bd9Sstevel@tonic-gate return (0); 304*7c478bd9Sstevel@tonic-gate } 305