]> git.ipfire.org Git - thirdparty/dhcp.git/blame - common/resolv.c
- Silence benign static analysis warnings.
[thirdparty/dhcp.git] / common / resolv.c
CommitLineData
a7de06ee
TL
1/* resolv.c
2
3 Parser for /etc/resolv.conf file. */
4
5/*
dc9d7b08
MA
6 * Copyright (c) 2009,2013 by Internet Systems Consortium, Inc. ("ISC")
7 * Copyright (c) 2004-2007 by Internet Systems Consortium, Inc. ("ISC")
98311e4b 8 * Copyright (c) 1996-2003 by Internet Software Consortium
a7de06ee 9 *
98311e4b
DH
10 * Permission to use, copy, modify, and distribute this software for any
11 * purpose with or without fee is hereby granted, provided that the above
12 * copyright notice and this permission notice appear in all copies.
a7de06ee 13 *
98311e4b
DH
14 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
15 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
16 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
17 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
18 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
19 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
20 * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
a7de06ee 21 *
98311e4b
DH
22 * Internet Systems Consortium, Inc.
23 * 950 Charter Street
24 * Redwood City, CA 94063
25 * <info@isc.org>
2c85ac9b 26 * https://www.isc.org/
49733f31 27 *
98311e4b 28 * This software has been written for Internet Systems Consortium
49733f31 29 * by Ted Lemon in cooperation with Vixie Enterprises and Nominum, Inc.
98311e4b 30 * To learn more about Internet Systems Consortium, see
2c85ac9b 31 * ``https://www.isc.org/''. To learn more about Vixie Enterprises,
49733f31
TL
32 * see ``http://www.vix.com''. To learn more about Nominum, Inc., see
33 * ``http://www.nominum.com''.
a7de06ee
TL
34 */
35
a7de06ee 36#include "dhcpd.h"
a7de06ee
TL
37
38struct name_server *name_servers;
39struct domain_search_list *domains;
40char path_resolv_conf [] = _PATH_RESOLV_CONF;
41
42void read_resolv_conf (parse_time)
43 TIME parse_time;
44{
3b4f8a4a
TL
45 int file;
46 struct parse *cfile;
b1b7b521 47 const char *val;
a7de06ee 48 int token;
a7de06ee
TL
49 struct name_server *sp, *sl, *ns;
50 struct domain_search_list *dp, *dl, *nd;
c40e954c 51 isc_result_t status;
a7de06ee 52
3e4618c4 53 if ((file = open (path_resolv_conf, O_RDONLY)) < 0) {
8ae2d595 54 log_error ("Can't open %s: %m", path_resolv_conf);
732a90b2
TL
55 return;
56 }
57
c40e954c
EH
58 cfile = NULL;
59 status = new_parse(&cfile, file, NULL, 0, path_resolv_conf, 1);
60 if (status != ISC_R_SUCCESS || cfile == NULL)
61 return;
3b4f8a4a 62
a7de06ee 63 do {
b3519f23 64 token = next_token (&val, (unsigned *)0, cfile);
0b69dcc8 65 if (token == END_OF_FILE)
a7de06ee
TL
66 break;
67 else if (token == EOL)
68 continue;
69 else if (token == DOMAIN || token == SEARCH) {
70 do {
71 struct domain_search_list *nd, **dp;
72 char *dn;
73
74 dn = parse_host_name (cfile);
75 if (!dn)
76 break;
77
78 dp = &domains;
79 for (nd = domains; nd; nd = nd -> next) {
80 dp = &nd -> next;
81 if (!strcmp (nd -> domain, dn))
82 break;
83 }
84 if (!nd) {
4bd8800e 85 nd = new_domain_search_list (MDL);
a7de06ee 86 if (!nd)
3b4f8a4a
TL
87 log_fatal ("No memory for %s",
88 dn);
a7de06ee
TL
89 nd -> next =
90 (struct domain_search_list *)0;
91 *dp = nd;
92 nd -> domain = dn;
a7de06ee
TL
93 }
94 nd -> rcdate = parse_time;
b3519f23
TL
95 token = peek_token (&val,
96 (unsigned *)0, cfile);
2c50133e 97 } while (token != EOL);
a7de06ee 98 if (token != EOL) {
3b4f8a4a
TL
99 parse_warn (cfile,
100 "junk after domain declaration");
a7de06ee
TL
101 skip_to_semi (cfile);
102 }
dc9d7b08 103 skip_token(&val, (unsigned *)0, cfile);
a7de06ee
TL
104 } else if (token == NAMESERVER) {
105 struct name_server *ns, **sp;
106 struct iaddr iaddr;
107
108 parse_ip_addr (cfile, &iaddr);
109
110 sp = &name_servers;
111 for (ns = name_servers; ns; ns = ns -> next) {
112 sp = &ns -> next;
113 if (!memcmp (&ns -> addr.sin_addr,
114 iaddr.iabuf, iaddr.len))
115 break;
116 }
117 if (!ns) {
4bd8800e 118 ns = new_name_server (MDL);
a7de06ee 119 if (!ns)
3b4f8a4a 120 log_fatal ("No memory for nameserver %s",
a7de06ee
TL
121 piaddr (iaddr));
122 ns -> next = (struct name_server *)0;
123 *sp = ns;
124 memcpy (&ns -> addr.sin_addr,
125 iaddr.iabuf, iaddr.len);
126#ifdef HAVE_SA_LEN
127 ns -> addr.sin_len = sizeof ns -> addr;
128#endif
129 ns -> addr.sin_family = AF_INET;
130 ns -> addr.sin_port = htons (53);
131 memset (ns -> addr.sin_zero, 0,
132 sizeof ns -> addr.sin_zero);
133 }
134 ns -> rcdate = parse_time;
135 skip_to_semi (cfile);
357708da
TL
136 } else
137 skip_to_semi (cfile); /* Ignore what we don't grok. */
a7de06ee 138 } while (1);
dc9d7b08 139 skip_token(&val, (unsigned *)0, cfile);
a7de06ee
TL
140
141 /* Lose servers that are no longer in /etc/resolv.conf. */
142 sl = (struct name_server *)0;
143 for (sp = name_servers; sp; sp = ns) {
144 ns = sp -> next;
145 if (sp -> rcdate != parse_time) {
146 if (sl)
147 sl -> next = sp -> next;
148 else
149 name_servers = sp -> next;
7e204261
TL
150 /* We can't actually free the name server structure,
151 because somebody might be hanging on to it. If
152 your /etc/resolv.conf file changes a lot, this
20ae1aff 153 could be a noticeable memory leak. */
a7de06ee
TL
154 } else
155 sl = sp;
156 }
157
158 /* Lose domains that are no longer in /etc/resolv.conf. */
159 dl = (struct domain_search_list *)0;
160 for (dp = domains; dp; dp = nd) {
161 nd = dp -> next;
162 if (dp -> rcdate != parse_time) {
163 if (dl)
164 dl -> next = dp -> next;
165 else
166 domains = dp -> next;
4bd8800e 167 free_domain_search_list (dp, MDL);
a7de06ee
TL
168 } else
169 dl = dp;
170 }
3b4f8a4a 171 end_parse (&cfile);
a7de06ee
TL
172}
173
174/* Pick a name server from the /etc/resolv.conf file. */
175
7e204261 176struct name_server *first_name_server ()
a7de06ee 177{
a7de06ee
TL
178 static TIME rcdate;
179 struct stat st;
180
181 /* Check /etc/resolv.conf and reload it if it's changed. */
182 if (cur_time > rcdate) {
732a90b2 183 if (stat (path_resolv_conf, &st) < 0) {
8ae2d595 184 log_error ("Can't stat %s", path_resolv_conf);
7e204261 185 return (struct name_server *)0;
732a90b2 186 }
a7de06ee 187 if (st.st_mtime > rcdate) {
a7de06ee
TL
188 rcdate = cur_time + 1;
189
190 read_resolv_conf (rcdate);
191 }
192 }
193
7e204261 194 return name_servers;
a7de06ee 195}