Watt-32 tcp/ip  2.2 dev-rel.10
res_init.c
Go to the documentation of this file.
1 
5 /* ++Copyright++ 1985, 1989, 1993
6  * -
7  * Copyright (c) 1985, 1989, 1993
8  * The Regents of the University of California. All rights reserved.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  * 1. Redistributions of source code must retain the above copyright
14  * notice, this list of conditions and the following disclaimer.
15  * 2. Redistributions in binary form must reproduce the above copyright
16  * notice, this list of conditions and the following disclaimer in the
17  * documentation and/or other materials provided with the distribution.
18  * 3. All advertising materials mentioning features or use of this software
19  * must display the following acknowledgement:
20  * This product includes software developed by the University of
21  * California, Berkeley and its contributors.
22  * 4. Neither the name of the University nor the names of its contributors
23  * may be used to endorse or promote products derived from this software
24  * without specific prior written permission.
25  *
26  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
27  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
29  * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
30  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
31  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
32  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
33  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
34  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
35  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36  * SUCH DAMAGE.
37  * -
38  * Portions Copyright (c) 1993 by Digital Equipment Corporation.
39  *
40  * Permission to use, copy, modify, and distribute this software for any
41  * purpose with or without fee is hereby granted, provided that the above
42  * copyright notice and this permission notice appear in all copies, and that
43  * the name of Digital Equipment Corporation not be used in advertising or
44  * publicity pertaining to distribution of the document or software without
45  * specific, written prior permission.
46  *
47  * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
48  * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
49  * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT
50  * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
51  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
52  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
53  * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
54  * SOFTWARE.
55  * -
56  * --Copyright--
57  */
58 
59 #include "resolver.h"
60 
61 #if defined(USE_BIND)
62 
63 /*----------------- info about "sortlist" -----------------------------
64  *
65  * Marc Majka 1994/04/16
66  * Allan Nathanson 1994/10/29 (BIND 4.9.3.x)
67  *
68  * NetInfo resolver configuration directory support.
69  *
70  * Allow a NetInfo directory to be created in the hierarchy which
71  * contains the same information as the resolver configuration file.
72  *
73  * - The local domain name is stored as the value of the "domain" property.
74  * - The Internet address(es) of the name server(s) are stored as values
75  * of the "nameserver" property.
76  * - The name server addresses are stored as values of the "nameserver"
77  * property.
78  * - The search list for host-name lookup is stored as values of the
79  * "search" property.
80  * - The sortlist comprised of IP address netmask pairs are stored as
81  * values of the "sortlist" property. The IP address and optional netmask
82  * should be seperated by a slash (/) or ampersand (&) character.
83  * - Internal resolver variables can be set from the value of the "options"
84  * property.
85  */
86 
87 #undef is_it
88 #define is_it(cp,x) !strncmp(cp,x,sizeof(x)-1)
89 
90 #ifndef INADDR_LOOPBACK
91 #define INADDR_LOOPBACK (u_long)0x7F000001
92 #endif
93 
94 char *res_cfg_options = NULL; /* resolver options */
95 char *res_cfg_aliases = NULL; /* hostaliases file */
96 
97 /*
98  * Resolver state default settings.
99  */
100 struct __res_state _res;
101 
102 static void res_setoptions (const char *options, const char *source)
103 {
104  const char *cp = options;
105 
106  if (_res.options & RES_DEBUG)
107  (*_printf) (";; res_setoptions(\"%s\", \"%s\")...\n", options, source);
108 
109  while (*cp)
110  {
111  /* skip leading and inner runs of spaces
112  */
113  while (*cp == ' ' || *cp == '\t')
114  ++cp;
115 
116  /* search for and process individual options
117  */
118  if (is_it(cp,"ndots:"))
119  {
120  int i = atoi (cp + sizeof("ndots:") - 1);
121 
122  if (i <= RES_MAXNDOTS)
123  _res.ndots = i;
124  else _res.ndots = RES_MAXNDOTS;
125 
126  if (_res.options & RES_DEBUG)
127  (*_printf) (";;\tndots=%d\n", _res.ndots);
128  }
129  else if (is_it(cp,"debug"))
130  {
131  if (!(_res.options & RES_DEBUG))
132  {
133  (*_printf) (";; res_setoptions(\"%s\", \"%s\")..\n", options, source);
134  _res.options |= RES_DEBUG;
135  }
136  (*_printf) (";;\tdebug\n");
137  }
138  else
139  {
140  /* XXX - print a warning here? */
141  }
142  /* skip to next run of spaces
143  */
144  while (*cp && *cp != ' ' && *cp != '\t')
145  cp++;
146  }
147 }
148 
149 u_int16_t W32_CALL res_randomid (void)
150 {
151  return (0xFFFF & rand());
152 }
153 
154 
155 /*
156  * Set up default settings. If the configuration file exist, the values
157  * there will have precedence. Otherwise, the server address is set to
158  * INADDR_ANY and the default domain name comes from the gethostname().
159  *
160  * An interrim version of this code (BIND 4.9, pre-4.4BSD) used 127.0.0.1
161  * rather than INADDR_ANY ("0.0.0.0") as the default name server address
162  * since it was noted that INADDR_ANY actually meant ``the first interface
163  * you "ifconfig"'d at boot time'' and if this was a SLIP or PPP interface,
164  * it had to be "up" in order for you to reach your own name server. It
165  * was later decided that since the recommended practice is to always
166  * install local static routes through 127.0.0.1 for all your network
167  * interfaces, that we could solve this problem without a code change.
168  *
169  * The configuration file should always be used, since it is the only way
170  * to specify a default domain. If you are running a server on your local
171  * machine, you should say "nameserver 0.0.0.0" or "nameserver 127.0.0.1"
172  * in the configuration file.
173  *
174  * Return 0 if completes successfully, -1 on error
175  */
176 int W32_CALL res_init (void)
177 {
178  char *cp;
179  char dom[MAX_HOSTLEN];
180  char buf[BUFSIZ];
181  int nserv;
182 
183  watt_sock_init (0, 0, 0);
184 
185  /*
186  * These three fields used to be statically initialized. This made
187  * it hard to use this code in a shared library. It is necessary,
188  * now that we're doing dynamic initialization here, that we preserve
189  * the old semantics: if an application modifies one of these three
190  * fields of _res before res_init() is called, res_init() will not
191  * alter them. Of course, if an application is setting them to
192  * _zero_ before calling res_init(), hoping to override what used
193  * to be the static default, we can't detect it and unexpected results
194  * will follow. Zero for any of these fields would make no sense,
195  * so one can safely assume that the applications were already getting
196  * unexpected results.
197  *
198  * _res.options is tricky since some apps were known to diddle the bits
199  * before res_init() was first called. We can't replicate that semantic
200  * with dynamic initialization (they may have turned bits off that are
201  * set in RES_DEFAULT). Our solution is to declare such applications
202  * "broken". They could fool us by setting RES_INIT but none do (yet).
203  */
204  if (!_res.retrans) _res.retrans = RES_TIMEOUT;
205  if (!_res.retry) _res.retry = 4;
206  if (!(_res.options & RES_INIT)) _res.options = RES_DEFAULT;
207 
208  /*
209  * This one used to initialize implicitly to zero, so unless the app
210  * has set it to something in particular, we can randomize it now.
211  */
212  if (_res.id == 0)
213  _res.id = res_randomid();
214 
215  _res.nsaddr.sin_addr.s_addr = INADDR_ANY;
216  _res.nsaddr.sin_family = AF_INET;
217  _res.nsaddr.sin_port = htons (NAMESERVER_PORT);
218  _res.nscount = 0;
219  _res.pfcode = 0;
220  _res.dnsrch[0] = _res.defdname;
221  _res.dnsrch[1] = NULL;
222  if (!(_res.options & RES_INIT))
223  _res.ndots = 1;
224 
225  if (getdomainname (dom,sizeof(dom)) == 0)
226  {
227  strncpy (_res.defdname, dom, sizeof(_res.defdname)-1);
228  _res.defdname [sizeof(_res.defdname)-1] = '\0';
229  }
230  else
231  _res.defdname[0] = 0;
232 
233  for (nserv = 0; nserv < MAXNS; nserv++)
234  {
235  _res.nsaddr_list[nserv].sin_family = AF_INET;
236  _res.nsaddr_list[nserv].sin_port = htons (NAMESERVER_PORT);
237  if (nserv < last_nameserver)
238  {
239  _res.nsaddr_list[nserv].sin_addr.s_addr = htonl (def_nameservers[nserv]);
240  _res.nscount++;
241  }
242  else
243  _res.nsaddr_list[nserv].sin_addr.s_addr = htonl (INADDR_LOOPBACK);
244  }
245 
246  if (_res.options & RES_DEBUG)
247  {
248  int i;
249  for (i = 1; i <= _res.nscount; i++)
250  (*_printf) ("Nameserv #%d: %s (%d)\n",
251  i, inet_ntoa(_res.nsaddr_list[i-1].sin_addr),
252  NAMESERVER_PORT);
253  }
254 
255  if (_res.defdname[0] == 0 &&
256  gethostname (buf,sizeof(_res.defdname)-1) == 0 &&
257  (cp = strchr(buf, '.')) != NULL)
258  strcpy (_res.defdname, cp+1);
259 
260  cp = getenv ("RES_OPTIONS");
261  if (!cp)
262  cp = res_cfg_options;
263  if (cp)
264  res_setoptions (cp, "env");
265 
266  _res.options |= RES_INIT;
267  return (0);
268 }
269 
270 /*
271  * Configure hook routine for bind resolver. Must be called
272  * before res_init() (via watt_sock_init).
273  */
274 static void (W32_CALL *prev_hook) (const char*, const char*);
275 
276 static const struct config_table bind_cfg[] = {
277  { "RES_OPTIONS", ARG_STRDUP, (void*)&res_cfg_options },
278  { "HOSTALIASES", ARG_STRDUP, (void*)&res_cfg_aliases },
279  { NULL, 0, NULL }
280  };
281 
282 static void W32_CALL resolver_init (const char *name, const char *value)
283 {
284  if (!parse_config_table(&bind_cfg[0], "BIND.", name, value) && prev_hook)
285  (*prev_hook) (name, value);
286 }
287 
288 static void res_exit (void)
289 {
290  DO_FREE (res_cfg_options);
291  DO_FREE (res_cfg_aliases);
292 }
293 
294 void W32_CALL res_init0 (void)
295 {
296  prev_hook = usr_init;
297  usr_init = resolver_init;
298  RUNDOWN_ADD (res_exit, 200);
299 }
300 #endif /* USE_BIND */
301 
int W32_CALL parse_config_table(const struct config_table *tab, const char *section, const char *name, const char *value)
Parse the config-table and if a match is found for ('section'+'.
Definition: pcconfig.c:379
int W32_CALL watt_sock_init(size_t tcp_Sock_size, size_t udp_Sock_size, size_t time_t_size)
Definition: sock_ini.c:749
int W32_CALL getdomainname(char *buffer, size_t buflen)
BSD-style: Return domain name of this host.
Definition: bsdname.c:186
duplicate string value
Definition: tcp.h:431