File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / dhcp / common / resolv.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Tue Oct 9 09:06:54 2012 UTC (11 years, 8 months ago) by misho
Branches: dhcp, MAIN
CVS tags: v4_1_R7p0, v4_1_R7, v4_1_R4, HEAD
dhcp 4.1 r7

    1: /* resolv.c
    2: 
    3:    Parser for /etc/resolv.conf file. */
    4: 
    5: /*
    6:  * Copyright (c) 2004-2007,2009 by Internet Systems Consortium, Inc. ("ISC")
    7:  * Copyright (c) 1996-2003 by Internet Software Consortium
    8:  *
    9:  * Permission to use, copy, modify, and distribute this software for any
   10:  * purpose with or without fee is hereby granted, provided that the above
   11:  * copyright notice and this permission notice appear in all copies.
   12:  *
   13:  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
   14:  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
   15:  * MERCHANTABILITY AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR
   16:  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
   17:  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
   18:  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
   19:  * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
   20:  *
   21:  *   Internet Systems Consortium, Inc.
   22:  *   950 Charter Street
   23:  *   Redwood City, CA 94063
   24:  *   <info@isc.org>
   25:  *   https://www.isc.org/
   26:  *
   27:  * This software has been written for Internet Systems Consortium
   28:  * by Ted Lemon in cooperation with Vixie Enterprises and Nominum, Inc.
   29:  * To learn more about Internet Systems Consortium, see
   30:  * ``https://www.isc.org/''.  To learn more about Vixie Enterprises,
   31:  * see ``http://www.vix.com''.   To learn more about Nominum, Inc., see
   32:  * ``http://www.nominum.com''.
   33:  */
   34: 
   35: #include "dhcpd.h"
   36: 
   37: struct name_server *name_servers;
   38: struct domain_search_list *domains;
   39: char path_resolv_conf [] = _PATH_RESOLV_CONF;
   40: 
   41: void read_resolv_conf (parse_time)
   42: 	TIME parse_time;
   43: {
   44: 	int file;
   45: 	struct parse *cfile;
   46: 	const char *val;
   47: 	int token;
   48: 	struct name_server *sp, *sl, *ns;
   49: 	struct domain_search_list *dp, *dl, *nd;
   50: 	isc_result_t status;
   51: 
   52: 	if ((file = open (path_resolv_conf, O_RDONLY)) < 0) {
   53: 		log_error ("Can't open %s: %m", path_resolv_conf);
   54: 		return;
   55: 	}
   56: 
   57: 	cfile = NULL;
   58: 	status = new_parse(&cfile, file, NULL, 0, path_resolv_conf, 1);
   59: 	if (status != ISC_R_SUCCESS || cfile == NULL)
   60: 		return;
   61: 
   62: 	do {
   63: 		token = next_token (&val, (unsigned *)0, cfile);
   64: 		if (token == END_OF_FILE)
   65: 			break;
   66: 		else if (token == EOL)
   67: 			continue;
   68: 		else if (token == DOMAIN || token == SEARCH) {
   69: 			do {
   70: 				struct domain_search_list *nd, **dp;
   71: 				char *dn;
   72: 
   73: 				dn = parse_host_name (cfile);
   74: 				if (!dn)
   75: 					break;
   76: 
   77: 				dp = &domains;
   78: 				for (nd = domains; nd; nd = nd -> next) {
   79: 					dp = &nd -> next;
   80: 					if (!strcmp (nd -> domain, dn))
   81: 						break;
   82: 				}
   83: 				if (!nd) {
   84: 					nd = new_domain_search_list (MDL);
   85: 					if (!nd)
   86: 						log_fatal ("No memory for %s",
   87: 							   dn);
   88: 					nd -> next =
   89: 						(struct domain_search_list *)0;
   90: 					*dp = nd;
   91: 					nd -> domain = dn;
   92: 					dn = (char *)0;
   93: 				}
   94: 				nd -> rcdate = parse_time;
   95: 				token = peek_token (&val,
   96: 						    (unsigned *)0, cfile);
   97: 			} while (token != EOL);
   98: 			if (token != EOL) {
   99: 				parse_warn (cfile,
  100: 					    "junk after domain declaration");
  101: 				skip_to_semi (cfile);
  102: 			}
  103: 			token = next_token (&val, (unsigned *)0, cfile);
  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) {
  118: 				ns = new_name_server (MDL);
  119: 				if (!ns)
  120: 				    log_fatal ("No memory for nameserver %s",
  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);
  136: 		} else
  137: 			skip_to_semi (cfile); /* Ignore what we don't grok. */
  138: 	} while (1);
  139: 	token = next_token (&val, (unsigned *)0, cfile);
  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;
  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
  153: 			   could be a noticeable memory leak. */
  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;
  167: 			free_domain_search_list (dp, MDL);
  168: 		} else
  169: 			dl = dp;
  170: 	}
  171: 	end_parse (&cfile);
  172: }
  173: 
  174: /* Pick a name server from the /etc/resolv.conf file. */
  175: 
  176: struct name_server *first_name_server ()
  177: {
  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) {
  183: 		if (stat (path_resolv_conf, &st) < 0) {
  184: 			log_error ("Can't stat %s", path_resolv_conf);
  185: 			return (struct name_server *)0;
  186: 		}
  187: 		if (st.st_mtime > rcdate) {
  188: 			rcdate = cur_time + 1;
  189: 			
  190: 			read_resolv_conf (rcdate);
  191: 		}
  192: 	}
  193: 
  194: 	return name_servers;
  195: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>