lwconfig.c revision 10a6f640ed599cbe4a8b98c46b71a61d24e5bbe7
a7038d1a0513c8e804937ebc95fc9cb3a46c04f5Mark Andrews * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC")
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence * Copyright (C) 2000-2003 Internet Software Consortium.
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley * Permission to use, copy, modify, and/or distribute this software for any
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley * purpose with or without fee is hereby granted, provided that the above
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence * copyright notice and this permission notice appear in all copies.
15a44745412679c30a6d022733925af70a38b715David Lawrence * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
15a44745412679c30a6d022733925af70a38b715David Lawrence * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
15a44745412679c30a6d022733925af70a38b715David Lawrence * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
15a44745412679c30a6d022733925af70a38b715David Lawrence * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
15a44745412679c30a6d022733925af70a38b715David Lawrence * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
15a44745412679c30a6d022733925af70a38b715David Lawrence * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
15a44745412679c30a6d022733925af70a38b715David Lawrence * PERFORMANCE OF THIS SOFTWARE.
80b782f356f0692c11b4e52e8dd46ec41704e5a2Mark Andrews/* $Id: lwconfig.c,v 1.47 2008/12/17 19:19:29 jinmei Exp $ */
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley * Module for parsing resolv.conf files.
def8e47c688e2480a4539d69c3d1a0a28a7c0550Mark Andrews * lwres_conf_init() creates an empty lwres_conf_t structure for
364a82f7c25b62967678027043425201a5e5171aBob Halley * lightweight resolver context ctx.
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence * lwres_conf_clear() frees up all the internal memory used by that
8dfa9caeec8e68db0c937e347a3d6629e7627d54Bob Halley * lwres_conf_t structure in resolver context ctx.
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley * lwres_conf_parse() opens the file filename and parses it to initialise
52637f592f705ca93fadc218e403fd55e8ce4aeaMark Andrews * the resolver context ctx's lwres_conf_t structure.
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley * lwres_conf_print() prints the lwres_conf_t structure for resolver
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley * context ctx to the FILE fp.
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley * \section lwconfig_return Return Values
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley * lwres_conf_parse() returns #LWRES_R_SUCCESS if it successfully read and
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley * parsed filename. It returns #LWRES_R_FAILURE if filename could not be
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley * opened or contained incorrect resolver statements.
078d49b63324f01d98301ee21671abee0c41fcdeBob Halley * lwres_conf_print() returns #LWRES_R_SUCCESS unless an error occurred
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley * when converting the network addresses to a numeric host address
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley * string. If this happens, the function returns #LWRES_R_FAILURE.
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley * \section lwconfig_see See Also
ca67883a666bdf314d3da958d5195e7215b1f797Bob Halley * stdio(3), \link resolver resolver \endlink
b12f0228b32775ee688ed21ddbf3a116c1adfb43Michael Graff * \section files Files
5619558151f1aa4249b3ead979e76876e29278b6Bob Halleylwres_conf_parsenameserver(lwres_context_t *ctx, FILE *fp);
5619558151f1aa4249b3ead979e76876e29278b6Bob Halleylwres_conf_parselwserver(lwres_context_t *ctx, FILE *fp);
5619558151f1aa4249b3ead979e76876e29278b6Bob Halleylwres_conf_parsedomain(lwres_context_t *ctx, FILE *fp);
5619558151f1aa4249b3ead979e76876e29278b6Bob Halleylwres_conf_parsesearch(lwres_context_t *ctx, FILE *fp);
5619558151f1aa4249b3ead979e76876e29278b6Bob Halleylwres_conf_parsesortlist(lwres_context_t *ctx, FILE *fp);
5619558151f1aa4249b3ead979e76876e29278b6Bob Halleylwres_conf_parseoption(lwres_context_t *ctx, FILE *fp);
5619558151f1aa4249b3ead979e76876e29278b6Bob Halleylwres_create_addr(const char *buff, lwres_addr_t *addr, int convert_zero);
bf345589ce0b0b64533d4566e4992a0e63aac6f5Bob Halley * Eat characters from FP until EOL or EOF. Returns EOF or '\n'
bf345589ce0b0b64533d4566e4992a0e63aac6f5Bob Halley * Eats white space up to next newline or non-whitespace character (of
bf345589ce0b0b64533d4566e4992a0e63aac6f5Bob Halley * EOF). Returns the last character read. Comments are considered white
7837d146219db7a85a4b444a9cdf6602254a4f75Bob Halley while (ch != '\n' && ch != EOF && isspace((unsigned char)ch))
bf345589ce0b0b64533d4566e4992a0e63aac6f5Bob Halley * Skip over any leading whitespace and then read in the next sequence of
bf345589ce0b0b64533d4566e4992a0e63aac6f5Bob Halley * non-whitespace characters. In this context newline is not considered
1c724c986de1449e3b2f1eeae4c724dc0d97603cBob Halley * whitespace. Returns EOF on end-of-file, or the character
732e0731dec1922747bb3b3147cf2c3d16b22eaaBob Halley * that caused the reading to stop.
7837d146219db7a85a4b444a9cdf6602254a4f75Bob Halley *p++ = (char)ch;
7837d146219db7a85a4b444a9cdf6602254a4f75Bob Halley } while (1);
1c724c986de1449e3b2f1eeae4c724dc0d97603cBob Halleystatic char *
1c724c986de1449e3b2f1eeae4c724dc0d97603cBob Halleylwres_strdup(lwres_context_t *ctx, const char *str) {
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley/*% intializes data structure for subsequent config parsing. */
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley for (i = 0; i < LWRES_CONFMAXNAMESERVERS; i++)
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley for (i = 0; i < LWRES_CONFMAXSEARCH; i++)
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley for (i = 0; i < LWRES_CONFMAXSORTLIST; i++) {
0180ccf72c79b98eb8ee5abbb7331aec6951dd9fBob Halley/*% Frees up all the internal memory used by the config data structure, returning it to the lwres_context_t. */
febaa091847ab004f40500cc475a819f2c73fcddAndreas Gustafsson lwres_resetaddr(&confdata->nameservers[i]);
febaa091847ab004f40500cc475a819f2c73fcddAndreas Gustafsson for (i = 0; i < confdata->searchnxt; i++) {
84185d19c7a9ef1ac23cc6236c8773697d4efeb1Brian Wellington for (i = 0; i < LWRES_CONFMAXSORTLIST; i++) {
5619558151f1aa4249b3ead979e76876e29278b6Bob Halleylwres_conf_parsenameserver(lwres_context_t *ctx, FILE *fp) {
c3b708aaf1bb0a118e0e11befa1b732acfb1d079Bob Halley if (confdata->nsnext == LWRES_CONFMAXNAMESERVERS)
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff return (LWRES_R_FAILURE); /* Nothing on line. */
b2ca6fd3a8293440b4d263723525396059cf2400Brian Wellington return (LWRES_R_FAILURE); /* Extra junk on line. */
b2ca6fd3a8293440b4d263723525396059cf2400Brian Wellington res = lwres_create_addr(word, &address, 1);
84185d19c7a9ef1ac23cc6236c8773697d4efeb1Brian Wellington ((address.family == LWRES_ADDRTYPE_V4 && ctx->use_ipv4 == 1) ||
89d8adb6663b13435ff9ae1eb53e45da7fa79275Bob Halley (address.family == LWRES_ADDRTYPE_V6 && ctx->use_ipv6 == 1))) {
c3b708aaf1bb0a118e0e11befa1b732acfb1d079Bob Halley confdata->nameservers[confdata->nsnext++] = address;
bf345589ce0b0b64533d4566e4992a0e63aac6f5Bob Halleylwres_conf_parselwserver(lwres_context_t *ctx, FILE *fp) {
febaa091847ab004f40500cc475a819f2c73fcddAndreas Gustafsson if (confdata->lwnext == LWRES_CONFMAXLWSERVERS)
febaa091847ab004f40500cc475a819f2c73fcddAndreas Gustafsson return (LWRES_R_FAILURE); /* Nothing on line. */
febaa091847ab004f40500cc475a819f2c73fcddAndreas Gustafsson return (LWRES_R_FAILURE); /* Extra junk on line. */
febaa091847ab004f40500cc475a819f2c73fcddAndreas Gustafsson &confdata->lwservers[confdata->lwnext++], 1);
2dd99c098ca162f985b7ef3c8142a964ad8281aeMark Andrewslwres_conf_parsedomain(lwres_context_t *ctx, FILE *fp) {
febaa091847ab004f40500cc475a819f2c73fcddAndreas Gustafsson return (LWRES_R_FAILURE); /* Nothing else on line. */
2dd99c098ca162f985b7ef3c8142a964ad8281aeMark Andrews return (LWRES_R_FAILURE); /* Extra junk on line. */
def8e47c688e2480a4539d69c3d1a0a28a7c0550Mark Andrews * Search and domain are mutually exclusive.
def8e47c688e2480a4539d69c3d1a0a28a7c0550Mark Andrews for (i = 0; i < LWRES_CONFMAXSEARCH; i++) {
2dd99c098ca162f985b7ef3c8142a964ad8281aeMark Andrews confdata->domainname = lwres_strdup(ctx, word);
def8e47c688e2480a4539d69c3d1a0a28a7c0550Mark Andrewslwres_conf_parsesearch(lwres_context_t *ctx, FILE *fp) {
febaa091847ab004f40500cc475a819f2c73fcddAndreas Gustafsson * Search and domain are mutually exclusive.
2dd99c098ca162f985b7ef3c8142a964ad8281aeMark Andrews * Remove any previous search definitions.
2dd99c098ca162f985b7ef3c8142a964ad8281aeMark Andrews for (idx = 0; idx < LWRES_CONFMAXSEARCH; idx++) {
76883e8cee593f45c65b0936e5d6e8f778d6e3efMichael Graff return (LWRES_R_FAILURE); /* Nothing else on line. */
76883e8cee593f45c65b0936e5d6e8f778d6e3efMichael Graff if (confdata->searchnxt == LWRES_CONFMAXSEARCH)
69be7837c920fac5c71a73e8fad586f9a2711e96Michael Graff confdata->search[idx] = lwres_strdup(ctx, word);
69be7837c920fac5c71a73e8fad586f9a2711e96Michael Grafflwres_create_addr(const char *buffer, lwres_addr_t *addr, int convert_zero) {
c3b708aaf1bb0a118e0e11befa1b732acfb1d079Bob Halley unsigned char zeroaddress[] = {0, 0, 0, 0};
febaa091847ab004f40500cc475a819f2c73fcddAndreas Gustafsson unsigned char loopaddress[] = {127, 0, 0, 1};
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff memcpy((void *)addr->address, &v4, NS_INADDRSZ);
13eaef2df27683658868c3828c18880d7419a16aDavid Lawrence } else if (lwres_net_pton(AF_INET6, buffer, &v6) == 1) {
13eaef2df27683658868c3828c18880d7419a16aDavid Lawrence memcpy((void *)addr->address, &v6, NS_IN6ADDRSZ);
03f91269f5453bcbd924910ef85a8f8496cf2661Mark Andrews return (LWRES_R_FAILURE); /* Unrecognised format. */
c3b708aaf1bb0a118e0e11befa1b732acfb1d079Bob Halleylwres_conf_parsesortlist(lwres_context_t *ctx, FILE *fp) {
ccbfddc70ef38263daca312d29bb8c5077e24785Bob Halley return (LWRES_R_FAILURE); /* Empty line after keyword. */
8dfa9caeec8e68db0c937e347a3d6629e7627d54Bob Halley if (confdata->sortlistnxt == LWRES_CONFMAXSORTLIST)
03f91269f5453bcbd924910ef85a8f8496cf2661Mark Andrews *p++ = '\0';
03f91269f5453bcbd924910ef85a8f8496cf2661Mark Andrews res = lwres_create_addr(word, &confdata->sortlist[idx].addr, 1);
03f91269f5453bcbd924910ef85a8f8496cf2661Mark Andrews * Make up a mask.
03f91269f5453bcbd924910ef85a8f8496cf2661Mark Andrews memset(&confdata->sortlist[idx].mask.address, 0xff,
03f91269f5453bcbd924910ef85a8f8496cf2661Mark Andrewslwres_conf_parseoption(lwres_context_t *ctx, FILE *fp) {
febaa091847ab004f40500cc475a819f2c73fcddAndreas Gustafsson return (LWRES_R_FAILURE); /* Empty line after keyword. */
84185d19c7a9ef1ac23cc6236c8773697d4efeb1Brian Wellington } else if (strcmp("no_tld_query", word) == 0) {
febaa091847ab004f40500cc475a819f2c73fcddAndreas Gustafsson } else if (strncmp("ndots:", word, 6) == 0) {
d981ca645597116d227a48bf37cc5edc061c854dBob Halley if (ndots < 0 || ndots > 0xff) /* Out of range. */
d981ca645597116d227a48bf37cc5edc061c854dBob Halley/*% parses a file and fills in the data structure. */
d981ca645597116d227a48bf37cc5edc061c854dBob Halleylwres_conf_parse(lwres_context_t *ctx, const char *filename) {
errno = 0;
return (LWRES_R_NOTFOUND);
return (ret);
int af;
if (p != tmp)
return (LWRES_R_FAILURE);
if (p != tmp)
return (LWRES_R_FAILURE);
if (p != tmp)
return (LWRES_R_FAILURE);
p = lwres_net_ntop
(af,
if (p != tmp)
return (LWRES_R_FAILURE);
return (LWRES_R_SUCCESS);