diff options
author | nectar <nectar@FreeBSD.org> | 2002-02-04 19:12:46 +0000 |
---|---|---|
committer | nectar <nectar@FreeBSD.org> | 2002-02-04 19:12:46 +0000 |
commit | ebeabb1ba32f14e308ae9aff9a2a7151265259cf (patch) | |
tree | 71ba64d0a82be4894e23f6d65f36b61203ec3875 /contrib/bind/lib | |
parent | 1385a0dca8f9199ece158336f4c6a9f1e2e03c3e (diff) | |
download | FreeBSD-src-ebeabb1ba32f14e308ae9aff9a2a7151265259cf.zip FreeBSD-src-ebeabb1ba32f14e308ae9aff9a2a7151265259cf.tar.gz |
Import of ISC BIND 8.3.1-REL.
Diffstat (limited to 'contrib/bind/lib')
121 files changed, 5535 insertions, 1422 deletions
diff --git a/contrib/bind/lib/Makefile b/contrib/bind/lib/Makefile index 1de1d01..489169f 100644 --- a/contrib/bind/lib/Makefile +++ b/contrib/bind/lib/Makefile @@ -13,7 +13,7 @@ # ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS # SOFTWARE. -# $Id: Makefile,v 8.25 2000/12/23 08:02:56 vixie Exp $ +# $Id: Makefile,v 8.26 2001/08/14 05:57:58 marka Exp $ SUBDIRS = resolv irs isc bsd inet nameser dst cylink dnssafe @@ -60,6 +60,9 @@ LIBTS = ${TOP}/lib/libbind.ts LIBR = libbind_r.${A} LIBRTS = ${TOP}/lib/libbindr.ts +.NOTPARALLEL: +.NO_PARALLEL: + all depend clean install distclean:: @for x in ${SUBDIRS}; do \ (cd $$x; pwd; ${MAKE} ${MARGS} $@) || exit 1; \ diff --git a/contrib/bind/lib/dst/Makefile b/contrib/bind/lib/dst/Makefile index a5518bd..5503afa 100644 --- a/contrib/bind/lib/dst/Makefile +++ b/contrib/bind/lib/dst/Makefile @@ -13,7 +13,7 @@ # ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS # SOFTWARE. -# $Id: Makefile,v 1.18 2000/12/23 08:02:58 vixie Exp $ +# $Id: Makefile,v 1.19 2001/08/14 05:58:03 marka Exp $ # these are only appropriate for BSD 4.4 or derivatives, and are used in # development. normal builds will be done in the top level directory and @@ -64,7 +64,7 @@ ${LIBBIND}: ${OBJS} ${RANLIB} ${LIBBIND} .c.${O}: - if test ! -d ${THREADED} ; then mkdir ${THREADED} ; else true ; fi + mkdir ${THREADED} 2> /dev/null || test -d ${THREADED} -a -w ${THREADED} ${CC} ${CPPFLAGS} ${CFLAGS} ${BOUNDS} ${REENTRANT} ${CRYPTINCL} ${CRYPTFLAGS} -c $*.c -o ${THREADED}/$*.${O} -${LDS} ${LD} ${LD_LIBFLAGS} ${THREADED}/$*.${O} \ -o ${THREADED}/$*.out && \ diff --git a/contrib/bind/lib/dst/bsafe_link.c b/contrib/bind/lib/dst/bsafe_link.c index ec072b3..7c9e481 100644 --- a/contrib/bind/lib/dst/bsafe_link.c +++ b/contrib/bind/lib/dst/bsafe_link.c @@ -1,5 +1,5 @@ #if defined(BSAFE) || defined(DNSSAFE) -static const char rcsid[] = "$Header: /proj/cvs/isc/bind8/src/lib/dst/bsafe_link.c,v 1.12 2001/04/05 21:59:59 bwelling Exp $"; +static const char rcsid[] = "$Header: /proj/cvs/isc/bind8/src/lib/dst/bsafe_link.c,v 1.15 2001/09/25 04:50:28 marka Exp $"; /* * Portions Copyright (c) 1995-1998 by Trusted Information Systems, Inc. @@ -118,7 +118,7 @@ static void *dst_bsafe_free_key_structure(void *key); * BSAFE/DNSSAFE related functions */ int -dst_bsafe_init() +dst_bsafe_init(void) { if (dst_t_func[KEY_RSA] != NULL) return (1); @@ -327,7 +327,8 @@ dst_bsafe_verify(const int mode, DST_KEY *dkey, void **context, if (ret == 0 && (status = B_DecryptUpdate(rsaEncryptor, work_area, &u_bytes, 0, - (u_char *) signature, sig_len, + (const u_char *) signature, + sig_len, NULL_PTR, NULL_SURRENDER))) ret = VERIFY_FINAL_FAILURE; @@ -385,24 +386,28 @@ dst_bsafe_to_dns_key(const DST_KEY *in_key, u_char *out_str, public = (B_KEY_OBJ)((RSA_Key *) in_key->dk_KEY_struct)->rk_Public_Key; n = B_GetKeyInfo((POINTER *) &pub, public, KI_RSAPublic); - - if (out_len < pub->exponent.len) /* not enough space */ + if (n != 0) return (-1); - if (pub->exponent.len < 256) /* key exponent is <= 2040 bits */ + + if (pub->exponent.len < 256) { /* key exponent is <= 2040 bits */ + if ((unsigned int)out_len < pub->exponent.len + 1) + return (-1); *op++ = (u_int8_t) pub->exponent.len; - else { /* key exponent is > 2040 bits */ + } else { /* key exponent is > 2040 bits */ u_int16_t e = (u_int16_t) pub->exponent.len; - *op++ = 0; /* 3 byte lenght field */ + if ((unsigned int)out_len < pub->exponent.len + 3) + return (-1); + *op++ = 0; /* 3 byte length field */ dst_s_put_int16(op, e); op += sizeof(e); n = 2; } - n += pub->exponent.len; - memcpy(op, pub->exponent.data, n); - op += n; n++; + memcpy(op, pub->exponent.data, pub->exponent.len); + op += pub->exponent.len; + n += pub->exponent.len; - if ((out_len - n) > pub->modulus.len) { + if ((unsigned int)(out_len - n) >= pub->modulus.len) { /*copy exponent */ memcpy(op, pub->modulus.data, pub->modulus.len); n += pub->modulus.len; @@ -612,7 +617,6 @@ dst_bsafe_key_from_file_format(DST_KEY *d_key, const char *buff, int status; char s[RAW_KEY_SIZE]; int len, s_len = sizeof(s); - int tag = -1; const char *p = buff; RSA_Key *b_key; A_RSA_KEY *public; @@ -1041,7 +1045,7 @@ dst_bsafe_md5digest(const int mode, B_ALGORITHM_OBJ *digest_obj, if (digest_obj == NULL || *digest_obj == NULL) { printf("NO digest obj\n"); - exit(-33); + exit(33); } if ((mode & SIG_MODE_INIT) && @@ -1050,8 +1054,7 @@ dst_bsafe_md5digest(const int mode, B_ALGORITHM_OBJ *digest_obj, return (SIGN_INIT_FAILURE); if ((mode & SIG_MODE_UPDATE) && data && (len > 0) && - (status = B_DigestUpdate(*digest_obj, (u_char *) data, len, - NULL_SURRENDER))) + (status = B_DigestUpdate(*digest_obj, data, len, NULL_SURRENDER))) return (SIGN_UPDATE_FAILURE); if (mode & SIG_MODE_FINAL) { @@ -1080,13 +1083,13 @@ T_malloc(unsigned int len) } int -T_memcmp(POINTER firstBlock, POINTER secondBlock, unsigned int len) +T_memcmp(CPOINTER firstBlock, CPOINTER secondBlock, unsigned int len) { return (memcmp(firstBlock, secondBlock, len)); } void -T_memcpy(POINTER output, POINTER input, unsigned int len) +T_memcpy(POINTER output, CPOINTER input, unsigned int len) { memcpy(output, input, len); } diff --git a/contrib/bind/lib/dst/cylink_link.c b/contrib/bind/lib/dst/cylink_link.c index 60097f5..6c2bdae 100644 --- a/contrib/bind/lib/dst/cylink_link.c +++ b/contrib/bind/lib/dst/cylink_link.c @@ -1,5 +1,5 @@ #ifdef CYLINK_DSS -static const char rcsid[] = "$Header: /proj/cvs/isc/bind8/src/lib/dst/cylink_link.c,v 1.8 2001/04/05 22:00:00 bwelling Exp $"; +static const char rcsid[] = "$Header: /proj/cvs/isc/bind8/src/lib/dst/cylink_link.c,v 1.9 2001/05/29 05:48:05 marka Exp $"; /* * Portions Copyright (c) 1995-1998 by Trusted Information Systems, Inc. @@ -147,7 +147,7 @@ dst_cylink_sign(const int mode, DST_KEY *dkey, void **context, SHAInit(ctx); if ((mode & SIG_MODE_UPDATE) && (data && len > 0)) { - status = SHAUpdate(ctx, (u_char *) data, len); + status = SHAUpdate(ctx, data, len); if (status != SUCCESS) return (SIGN_UPDATE_FAILURE); } @@ -228,7 +228,7 @@ dst_cylink_verify(const int mode, DST_KEY *dkey, void **context, SHAInit(ctx); if ((mode & SIG_MODE_UPDATE) && (data && len > 0)) { - status = SHAUpdate(ctx, (u_char *) data, len); + status = SHAUpdate(ctx, data, len); if (status != SUCCESS) return (VERIFY_UPDATE_FAILURE); } @@ -576,6 +576,8 @@ dst_cylink_generate_keypair(DST_KEY *key, int nothing) DSA_Key *dsa; u_char rand[SHA_LENGTH]; + UNUSED(nothing); + if (key == NULL || key->dk_alg != KEY_DSA) return (0); diff --git a/contrib/bind/lib/dst/dst_api.c b/contrib/bind/lib/dst/dst_api.c index a79dcf1..cc2a7e4 100644 --- a/contrib/bind/lib/dst/dst_api.c +++ b/contrib/bind/lib/dst/dst_api.c @@ -1,5 +1,5 @@ #ifndef LINT -static const char rcsid[] = "$Header: /proj/cvs/isc/bind8/src/lib/dst/dst_api.c,v 1.17.2.2 2001/07/26 01:58:06 marka Exp $"; +static const char rcsid[] = "$Header: /proj/cvs/isc/bind8/src/lib/dst/dst_api.c,v 1.20 2001/07/26 01:20:08 marka Exp $"; #endif /* @@ -62,8 +62,8 @@ static const char rcsid[] = "$Header: /proj/cvs/isc/bind8/src/lib/dst/dst_api.c, /* static variables */ static int done_init = 0; dst_func *dst_t_func[DST_MAX_ALGS]; -char *key_file_fmt_str = "Private-key-format: v%s\nAlgorithm: %d (%s)\n"; -char *dst_path = ""; +const char *key_file_fmt_str = "Private-key-format: v%s\nAlgorithm: %d (%s)\n"; +const char *dst_path = ""; /* internal I/O functions */ static DST_KEY *dst_s_read_public_key(const char *in_name, @@ -109,12 +109,14 @@ dst_init() } else if (stat(s, &statbuf) != 0 || !S_ISDIR(statbuf.st_mode)) { EREPORT(("%s is not a valid directory\n", s)); } else { - dst_path = (char *) malloc(len + 2); - memcpy(dst_path, s, len + 1); - if (dst_path[strlen(dst_path) - 1] != '/') { - dst_path[strlen(dst_path) + 1] = 0; - dst_path[strlen(dst_path)] = '/'; + char *tmp; + tmp = (char *) malloc(len + 2); + memcpy(tmp, s, len + 1); + if (tmp[strlen(tmp) - 1] != '/') { + tmp[strlen(tmp) + 1] = 0; + tmp[strlen(tmp)] = '/'; } + dst_path = tmp; } } memset(dst_t_func, 0, sizeof(dst_t_func)); @@ -555,7 +557,7 @@ dst_s_read_public_key(const char *in_name, const u_int16_t in_id, int in_alg) enckey[--len] = '\0'; /* remove leading spaces */ - for (notspace = (char *) enckey; isspace(*notspace); len--) + for (notspace = (char *) enckey; isspace((*notspace)&0xff); len--) notspace++; dlen = b64_pton(notspace, deckey, sizeof(deckey)); @@ -589,6 +591,7 @@ dst_s_write_public_key(const DST_KEY *key) u_char out_key[RAW_KEY_SIZE]; char enc_key[RAW_KEY_SIZE]; int len = 0; + int mode; memset(out_key, 0, sizeof(out_key)); if (key == NULL) { @@ -604,8 +607,10 @@ dst_s_write_public_key(const DST_KEY *key) key->dk_key_name, key->dk_id, PUBLIC_KEY)); return (0); } + /* XXX in general this should be a check for symmetric keys */ + mode = (key->dk_alg == KEY_HMAC_MD5) ? 0600 : 0644; /* create public key file */ - if ((fp = dst_s_fopen(filename, "w+", 0644)) == NULL) { + if ((fp = dst_s_fopen(filename, "w+", mode)) == NULL) { EREPORT(("DST_write_public_key: open of file:%s failed (errno=%d)\n", filename, errno)); return (0); diff --git a/contrib/bind/lib/dst/dst_internal.h b/contrib/bind/lib/dst/dst_internal.h index 66bfed4..0825109 100644 --- a/contrib/bind/lib/dst/dst_internal.h +++ b/contrib/bind/lib/dst/dst_internal.h @@ -65,13 +65,14 @@ typedef struct dst_key { #ifdef REPORT_ERRORS #define EREPORT(str) printf str #else -#define EREPORT(str) +#define EREPORT(str) (void)0 #endif /* use our own special macro to FRRE memory */ #ifndef SAFE_FREE -#define SAFE_FREE(a) if(a != NULL){memset(a,0, sizeof(*a)); free(a); a=NULL;} +#define SAFE_FREE(a) \ +do{if(a != NULL){memset(a,0, sizeof(*a)); free(a); a=NULL;}} while (0) #define SAFE_FREE2(a,s) if (a != NULL && s > 0){memset(a,0, s);free(a); a=NULL;} #endif @@ -98,22 +99,22 @@ typedef struct dst_func { } dst_func; extern dst_func *dst_t_func[DST_MAX_ALGS]; -extern char *key_file_fmt_str; -extern char *dst_path; +extern const char *key_file_fmt_str; +extern const char *dst_path; #ifndef DST_HASH_SIZE #define DST_HASH_SIZE 20 /* RIPEMD160 and SHA-1 are 20 bytes MD5 is 16 */ #endif -int dst_bsafe_init(); +int dst_bsafe_init(void); -int dst_rsaref_init(); +int dst_rsaref_init(void); -int dst_hmac_md5_init(); +int dst_hmac_md5_init(void); -int dst_cylink_init(); +int dst_cylink_init(void); -int dst_eay_dss_init(); +int dst_eay_dss_init(void); /* support functions */ /* base64 to bignum conversion routines */ @@ -158,6 +159,10 @@ void dst_s_put_int32( u_int8_t *buf, const u_int32_t val); #else # define DUMP(a,b,c,d) #endif +void +dst_s_dump(const int mode, const u_char *data, const int size, + const char *msg); + #endif /* DST_INTERNAL_H */ diff --git a/contrib/bind/lib/dst/eay_dss_link.c b/contrib/bind/lib/dst/eay_dss_link.c index 0cc01a8..b5c7caa 100644 --- a/contrib/bind/lib/dst/eay_dss_link.c +++ b/contrib/bind/lib/dst/eay_dss_link.c @@ -1,5 +1,5 @@ #ifdef EAY_DSS -static const char rcsid[] = "$Header: /proj/cvs/isc/bind8/src/lib/dst/eay_dss_link.c,v 1.5 2001/04/05 22:00:03 bwelling Exp $"; +static const char rcsid[] = "$Header: /proj/cvs/isc/bind8/src/lib/dst/eay_dss_link.c,v 1.6 2001/05/29 05:48:09 marka Exp $"; /* * Portions Copyright (c) 1995-1998 by Trusted Information Systems, Inc. @@ -44,6 +44,7 @@ static const char rcsid[] = "$Header: /proj/cvs/isc/bind8/src/lib/dst/eay_dss_li #include "port_after.h" + static int dst_eay_dss_sign(const int mode, DST_KEY *dkey, void **context, const u_char *data, const int len, u_char *signature, const int sig_len); @@ -71,7 +72,7 @@ static int dst_eay_dss_compare_keys(const DST_KEY *key1, const DST_KEY *key2); * EAY DSS related functions */ int -dst_eay_dss_init() +dst_eay_dss_init(void) { if (dst_t_func[KEY_DSA] != NULL) return (1); @@ -608,8 +609,21 @@ dst_eay_dss_compare_keys(const DST_KEY *key1, const DST_KEY *key2) return (0); } #else +#include "port_before.h" + +#include <stdio.h> +#include <unistd.h> +#include <stdlib.h> +#include <string.h> +#include <memory.h> +#include <sys/param.h> +#include <sys/time.h> +#include <netinet/in.h> + +#include "dst_internal.h" +#include "port_after.h" int -dst_eay_dss_init() +dst_eay_dss_init(void) { return (0); } diff --git a/contrib/bind/lib/dst/hmac_link.c b/contrib/bind/lib/dst/hmac_link.c index 1b93088..12e22a8 100644 --- a/contrib/bind/lib/dst/hmac_link.c +++ b/contrib/bind/lib/dst/hmac_link.c @@ -1,6 +1,6 @@ #ifdef HMAC_MD5 #ifndef LINT -static const char rcsid[] = "$Header: /proj/cvs/isc/bind8/src/lib/dst/hmac_link.c,v 1.8 1999/10/15 21:30:07 vixie Exp $"; +static const char rcsid[] = "$Header: /proj/cvs/isc/bind8/src/lib/dst/hmac_link.c,v 1.9 2001/05/29 05:48:10 marka Exp $"; #endif /* * Portions Copyright (c) 1995-1998 by Trusted Information Systems, Inc. @@ -103,7 +103,7 @@ dst_hmac_md5_sign(const int mode, DST_KEY *d_key, void **context, } if ((mode & SIG_MODE_UPDATE) && (data && len > 0)) - MD5Update(ctx, (u_char *)data, len); + MD5Update(ctx, data, len); if (mode & SIG_MODE_FINAL) { if (signature == NULL || sig_len < MD5_LEN) @@ -169,7 +169,7 @@ dst_hmac_md5_verify(const int mode, DST_KEY *d_key, void **context, MD5Update(ctx, key->hk_ipad, HMAC_LEN); } if ((mode & SIG_MODE_UPDATE) && (data && len > 0)) - MD5Update(ctx, (u_char *)data, len); + MD5Update(ctx, data, len); if (mode & SIG_MODE_FINAL) { u_char digest[MD5_LEN]; @@ -229,7 +229,7 @@ dst_buffer_to_hmac_md5(DST_KEY *dkey, const u_char *key, const int keylen) if (keylen > HMAC_LEN) { u_char tk[MD5_LEN]; MD5Init(&ctx); - MD5Update(&ctx, (u_char *)key, keylen); + MD5Update(&ctx, key, keylen); MD5Final(tk, &ctx); memset((void *) &ctx, 0, sizeof(ctx)); key = tk; @@ -431,6 +431,8 @@ dst_hmac_md5_generate_key(DST_KEY *key, const int nothing) u_char *buff; int i, n, size; + i = nothing; + if (key == NULL || key->dk_alg != KEY_HMAC_MD5) return (0); size = (key->dk_key_size + 7) / 8; /* convert to bytes */ diff --git a/contrib/bind/lib/dst/md5.h b/contrib/bind/lib/dst/md5.h index c8b1580..c886d17 100644 --- a/contrib/bind/lib/dst/md5.h +++ b/contrib/bind/lib/dst/md5.h @@ -80,7 +80,7 @@ typedef struct MD5state_st #ifndef NOPROTO void MD5_Init(MD5_CTX *c); -void MD5_Update(MD5_CTX *c, unsigned char *data, unsigned long len); +void MD5_Update(MD5_CTX *c, const unsigned char *data, unsigned long len); void MD5_Final(unsigned char *md, MD5_CTX *c); unsigned char *MD5(unsigned char *d, unsigned long n, unsigned char *md); #else diff --git a/contrib/bind/lib/dst/md5_dgst.c b/contrib/bind/lib/dst/md5_dgst.c index 82e5a38..78882d1 100644 --- a/contrib/bind/lib/dst/md5_dgst.c +++ b/contrib/bind/lib/dst/md5_dgst.c @@ -56,11 +56,13 @@ * [including the GNU Public Licence.] */ -#include <stdio.h> #ifdef USE_MD5 /* Added by ogud@tis.com 1998/1/26 */ +#include <port_before.h> +#include <stdio.h> #include "md5_locl.h" +#include <port_after.h> -char *MD5_version="MD5 part of SSLeay 0.8.1 19-Jul-1997"; +const char *MD5_version="MD5 part of SSLeay 0.8.1 19-Jul-1997"; /* Implemented from RFC1321 The MD5 Message-Digest Algorithm */ @@ -90,7 +92,7 @@ MD5_CTX *c; void MD5_Update(c, data, len) MD5_CTX *c; -register unsigned char *data; +register const unsigned char *data; unsigned long len; { register ULONG *p; diff --git a/contrib/bind/lib/dst/prandom.c b/contrib/bind/lib/dst/prandom.c index 031da2e..2236fe8 100644 --- a/contrib/bind/lib/dst/prandom.c +++ b/contrib/bind/lib/dst/prandom.c @@ -1,5 +1,5 @@ #ifndef LINT -static const char rcsid[] = "$Header: /proj/cvs/isc/bind8/src/lib/dst/prandom.c,v 1.10 2001/02/12 23:13:46 marka Exp $"; +static const char rcsid[] = "$Header: /proj/cvs/isc/bind8/src/lib/dst/prandom.c,v 1.12 2001/07/26 01:20:09 marka Exp $"; #endif /* * Portions Copyright (c) 1995-1998 by Trusted Information Systems, Inc. @@ -119,9 +119,9 @@ static int unix_cmd(dst_work *work); static int digest_file(dst_work *work); static void force_hash(dst_work *work, prand_hash *hash); -static int do_hash(dst_work *work, prand_hash *hash, u_char *input, +static int do_hash(dst_work *work, prand_hash *hash, const u_char *input, int size); -static int my_digest(dst_work *tmp, u_char *input, int size); +static int my_digest(dst_work *tmp, const u_char *input, int size); static prand_hash *get_hmac_key(int step, int block); static int own_random(dst_work *work); @@ -257,11 +257,10 @@ do_ls(dst_work *work) else if (i==1) /* if starting a new round cut what we accept */ d_round += (tv.tv_sec - d_round)/2; - if (buf.st_atime < d_round) + if (buf.st_atime < (time_t)d_round) return (0); - EREPORT(("do_ls i %d filled %4d in_temp %4d\n", - i-1, work->filled, work->in_temp)); + EREPORT(("do_ls i %d filled %4d\n", i-1, work->filled)); memcpy(tmp_buff, &buf, sizeof(buf)); tb_i += sizeof(buf); @@ -322,8 +321,7 @@ unix_cmd(dst_work *work) if (cmds[cmd_index] == NULL) cmd_index = 0; - EREPORT(("unix_cmd() i %d filled %4d in_temp %4d\n", - cmd_index, work->filled, work->in_temp)); + EREPORT(("unix_cmd() i %d filled %4d\n", cmd_index, work->filled)); pipe = popen(cmds[cmd_index++], "r"); /* execute the command */ while ((n = fread(buffer, sizeof(char), sizeof(buffer), pipe)) > 0) { @@ -334,7 +332,7 @@ unix_cmd(dst_work *work) cnt += do_time(work); } while ((n = fread(buffer, sizeof(char), sizeof(buffer), pipe)) > 0) - NULL; /* drain the pipe */ + (void)NULL; /* drain the pipe */ pclose(pipe); return (cnt); /* read how many bytes where read in */ } @@ -377,7 +375,7 @@ digest_file(dst_work *work) } if (access(name, R_OK) || stat(name, &st)) return (0); /* no such file or not allowed to read it */ - if (strncmp(name, "/proc/", 6) && st.st_mtime < f_round) + if (strncmp(name, "/proc/", 6) && st.st_mtime < (time_t)f_round) return(0); /* file has not changed recently enough */ if (dst_sign_data(SIG_MODE_INIT, work->file_digest, &ctx, NULL, 0, NULL, 0)) { @@ -401,7 +399,7 @@ digest_file(dst_work *work) } else if (i > 0) my_digest(work, buf, i); - my_digest(work, (u_char *)name, strlen(name)); + my_digest(work, (const u_char *)name, strlen(name)); return (no + strlen(name)); } @@ -439,9 +437,10 @@ force_hash(dst_work *work, prand_hash *hash) * */ static int -do_hash(dst_work *work, prand_hash *hash, u_char *input, int size) +do_hash(dst_work *work, prand_hash *hash, const u_char *input, int size) { - u_char *tmp = input, *tp; + const u_char *tmp = input; + u_char *save = NULL, *tp; int i, cnt = size, n, needed, avail, dig, tmp_size = 0; if (cnt <= 0 || input == NULL) @@ -449,7 +448,7 @@ do_hash(dst_work *work, prand_hash *hash, u_char *input, int size) if (hash->step > 1) { /* if using subset of input data */ tmp_size = size / hash->step + 2; - tp = tmp = malloc(tmp_size); + tmp = tp = save = malloc(tmp_size); for (cnt = 0, i = hash->curr; i < size; i += hash->step, cnt++) *(tp++) = input[i]; /* calcutate the starting point in the next input set */ @@ -466,13 +465,13 @@ do_hash(dst_work *work, prand_hash *hash, u_char *input, int size) if (hash->digested >= hash->block) force_hash(work, hash); if (work->needed < work->filled) { - if (tmp != input) - SAFE_FREE2(tmp, tmp_size); + if (tmp_size > 0) + SAFE_FREE2(save, tmp_size); return (1); } } if (tmp_size > 0) - SAFE_FREE2(tmp, tmp_size); + SAFE_FREE2(save, tmp_size); return (0); } @@ -482,7 +481,7 @@ do_hash(dst_work *work, prand_hash *hash, u_char *input, int size) * if work-block needs more data, keep filling with the rest of the input. */ static int -my_digest(dst_work *work, u_char *input, int size) +my_digest(dst_work *work, const u_char *input, int size) { int i, full = 0; @@ -603,8 +602,8 @@ own_random(dst_work *work) * proceed while needed */ while (work->filled < work->needed) { - EREPORT(("own_random r %08x b %6d t %6d f %6d\n", - ran_val, bytes, work->in_temp, work->filled)); + EREPORT(("own_random r %08x b %6d f %6d\n", + ran_val, bytes, work->filled)); /* pick a random number in the range of 0..7 based on that random number * perform some operations that yield random data */ @@ -840,8 +839,10 @@ dst_s_semi_random(u_char *output, int size) i = dst_sign_data(SIG_MODE_ALL, my_key, NULL, (u_char *) counter, hb_size, semi_old, sizeof(semi_old)); +#ifdef REPORT_ERRORS if (i != hb_size) EREPORT(("HMAC SIGNATURE FAILURE %d\n", i)); +#endif cnt++; if (size - out < i) /* Not all data is needed */ semi_loc = i = size - out; diff --git a/contrib/bind/lib/dst/rsaref_link.c b/contrib/bind/lib/dst/rsaref_link.c index a45b6f7..8e09b86 100644 --- a/contrib/bind/lib/dst/rsaref_link.c +++ b/contrib/bind/lib/dst/rsaref_link.c @@ -1,5 +1,5 @@ #ifdef RSAREF -static const char rcsid[] = "$Header: /proj/cvs/isc/bind8/src/lib/dst/rsaref_link.c,v 1.9 2001/04/05 22:00:04 bwelling Exp $"; +static const char rcsid[] = "$Header: /proj/cvs/isc/bind8/src/lib/dst/rsaref_link.c,v 1.10 2001/05/29 05:48:15 marka Exp $"; /* * Portions Copyright (c) 1995-1998 by Trusted Information Systems, Inc. @@ -740,6 +740,19 @@ dst_rsaref_init_random_struct(R_RANDOM_STRUCT * randomstruct) #else +#include "port_before.h" + +#include <stdio.h> +#include <unistd.h> +#include <stdlib.h> +#include <string.h> +#include <memory.h> +#include <sys/param.h> +#include <sys/time.h> +#include <netinet/in.h> + +#include "dst_internal.h" +#include "port_after.h" int /* rsaref is not available */ dst_rsaref_init() { diff --git a/contrib/bind/lib/dst/support.c b/contrib/bind/lib/dst/support.c index 2dd2a8c..6cc0bd1 100644 --- a/contrib/bind/lib/dst/support.c +++ b/contrib/bind/lib/dst/support.c @@ -1,4 +1,4 @@ -static const char rcsid[] = "$Header: /proj/cvs/isc/bind8/src/lib/dst/support.c,v 1.9.2.1 2001/06/06 21:45:17 marka Exp $"; +static const char rcsid[] = "$Header: /proj/cvs/isc/bind8/src/lib/dst/support.c,v 1.11 2001/05/29 05:48:16 marka Exp $"; /* @@ -241,7 +241,7 @@ dst_s_dns_key_id(const u_char *dns_key_rdata, const int rdata_len) /* compute id */ if (dns_key_rdata[3] == KEY_RSA) /* Algorithm RSA */ - return dst_s_get_int16((u_char *) + return dst_s_get_int16((const u_char *) &dns_key_rdata[rdata_len - 3]); else if (dns_key_rdata[3] == KEY_HMAC_MD5) /* compatibility */ @@ -393,7 +393,7 @@ dst_s_build_filename(char *filename, const char *name, u_int16_t id, return (-1); my_id = id; sprintf(filename, "K%s+%03d+%05d.%s", name, alg, my_id, - (char *) suffix); + (const char *) suffix); if (strrchr(filename, '/')) return (-1); if (strrchr(filename, '\\')) @@ -420,7 +420,7 @@ dst_s_fopen(const char *filename, const char *mode, int perm) { FILE *fp; char pathname[PATH_MAX]; - int plen = sizeof(pathname); + size_t plen = sizeof(pathname); if (*dst_path != '\0') { strcpy(pathname, dst_path); @@ -444,6 +444,8 @@ void dst_s_dump(const int mode, const u_char *data, const int size, const char *msg) { + UNUSED(data); + if (size > 0) { #ifdef LONG_TEST static u_char scratch[1000]; diff --git a/contrib/bind/lib/inet/Makefile b/contrib/bind/lib/inet/Makefile index 1876bb6..a448e61 100644 --- a/contrib/bind/lib/inet/Makefile +++ b/contrib/bind/lib/inet/Makefile @@ -13,7 +13,7 @@ # ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS # SOFTWARE. -# $Id: Makefile,v 8.21 2000/12/23 08:02:59 vixie Exp $ +# $Id: Makefile,v 8.23 2001/08/14 05:58:05 marka Exp $ # these are only appropriate for BSD 4.4 or derivatives, and are used in # development. normal builds will be done in the top level directory and @@ -45,12 +45,14 @@ THREADED= threaded SRCS= nsap_addr.c inet_addr.c inet_ntop.c inet_pton.c \ inet_ntoa.c inet_neta.c inet_net_ntop.c inet_net_pton.c \ inet_cidr_ntop.c inet_cidr_pton.c \ - inet_lnaof.c inet_makeaddr.c inet_netof.c inet_network.c + inet_lnaof.c inet_makeaddr.c inet_netof.c inet_network.c \ + inet_data.c OBJS= nsap_addr.${O} inet_addr.${O} inet_ntop.${O} inet_pton.${O} \ inet_ntoa.${O} inet_neta.${O} inet_net_ntop.${O} inet_net_pton.${O} \ inet_cidr_ntop.${O} inet_cidr_pton.${O} \ - inet_lnaof.${O} inet_makeaddr.${O} inet_netof.${O} inet_network.${O} + inet_lnaof.${O} inet_makeaddr.${O} inet_netof.${O} inet_network.${O} \ + inet_data.${O} all: ${LIBBIND} @@ -62,7 +64,7 @@ ${LIBBIND}: ${OBJS} ${RANLIB} ${LIBBIND} .c.${O}: - if test ! -d ${THREADED} ; then mkdir ${THREADED} ; else true ; fi + mkdir ${THREADED} 2> /dev/null || test -d ${THREADED} -a -w ${THREADED} ${CC} ${CPPFLAGS} ${CFLAGS} ${BOUNDS} ${REENTRANT} -c $*.c \ -o ${THREADED}/$*.${O} -${LDS} ${LD} ${LD_LIBFLAGS} ${THREADED}/$*.${O} \ diff --git a/contrib/bind/lib/inet/inet_addr.c b/contrib/bind/lib/inet/inet_addr.c index 3b54aa8..b68190c 100644 --- a/contrib/bind/lib/inet/inet_addr.c +++ b/contrib/bind/lib/inet/inet_addr.c @@ -70,7 +70,7 @@ #if defined(LIBC_SCCS) && !defined(lint) static const char sccsid[] = "@(#)inet_addr.c 8.1 (Berkeley) 6/17/93"; -static const char rcsid[] = "$Id: inet_addr.c,v 8.11 1999/10/13 16:39:25 vixie Exp $"; +static const char rcsid[] = "$Id: inet_addr.c,v 8.12 2001/05/29 05:48:18 marka Exp $"; #endif /* LIBC_SCCS and not lint */ #include "port_before.h" @@ -121,7 +121,7 @@ inet_aton(const char *cp, struct in_addr *addr) { * Values are specified as for C: * 0x=hex, 0=octal, isdigit=decimal. */ - if (!isdigit(c)) + if (!isdigit((unsigned char)c)) return (0); val = 0; base = 10; digit = 0; if (c == '0') { @@ -134,15 +134,16 @@ inet_aton(const char *cp, struct in_addr *addr) { } } for (;;) { - if (isascii(c) && isdigit(c)) { + if (isascii(c) && isdigit((unsigned char)c)) { if (base == 8 && (c == '8' || c == '9')) return (0); val = (val * base) + (c - '0'); c = *++cp; digit = 1; - } else if (base == 16 && isascii(c) && isxdigit(c)) { + } else if (base == 16 && isascii(c) && + isxdigit((unsigned char)c)) { val = (val << 4) | - (c + 10 - (islower(c) ? 'a' : 'A')); + (c + 10 - (islower((unsigned char)c) ? 'a' : 'A')); c = *++cp; digit = 1; } else @@ -165,7 +166,7 @@ inet_aton(const char *cp, struct in_addr *addr) { /* * Check for trailing characters. */ - if (c != '\0' && (!isascii(c) || !isspace(c))) + if (c != '\0' && (!isascii(c) || !isspace((unsigned char)c))) return (0); /* * Did we get a valid digit? diff --git a/contrib/bind/lib/inet/inet_cidr_ntop.c b/contrib/bind/lib/inet/inet_cidr_ntop.c index 08352ab..0acff76 100644 --- a/contrib/bind/lib/inet/inet_cidr_ntop.c +++ b/contrib/bind/lib/inet/inet_cidr_ntop.c @@ -16,7 +16,7 @@ */ #if defined(LIBC_SCCS) && !defined(lint) -static const char rcsid[] = "$Id: inet_cidr_ntop.c,v 8.4 1999/10/07 20:44:02 vixie Exp $"; +static const char rcsid[] = "$Id: inet_cidr_ntop.c,v 8.7 2001/09/28 05:19:36 marka Exp $"; #endif #include "port_before.h" @@ -24,6 +24,7 @@ static const char rcsid[] = "$Id: inet_cidr_ntop.c,v 8.4 1999/10/07 20:44:02 vix #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> +#include <arpa/nameser.h> #include <arpa/inet.h> #include <errno.h> @@ -41,6 +42,8 @@ static const char rcsid[] = "$Id: inet_cidr_ntop.c,v 8.4 1999/10/07 20:44:02 vix static char * inet_cidr_ntop_ipv4 __P((const u_char *src, int bits, char *dst, size_t size)); +static char * inet_cidr_ntop_ipv6 __P((const u_char *src, int bits, + char *dst, size_t size)); /* * char * @@ -61,12 +64,34 @@ inet_cidr_ntop(int af, const void *src, int bits, char *dst, size_t size) { switch (af) { case AF_INET: return (inet_cidr_ntop_ipv4(src, bits, dst, size)); + case AF_INET6: + return (inet_cidr_ntop_ipv6(src, bits, dst, size)); default: errno = EAFNOSUPPORT; return (NULL); } } +static int +decoct(const u_char *src, int bytes, char *dst, size_t size) { + char *odst = dst; + char *t; + int b; + + for (b = 1; b <= bytes; b++) { + if (size < sizeof "255.") + return (0); + t = dst; + dst += SPRINTF((dst, "%u", *src++)); + if (b != bytes) { + *dst++ = '.'; + *dst = '\0'; + } + size -= (size_t)(dst - t); + } + return (dst - odst); +} + /* * static char * * inet_cidr_ntop_ipv4(src, bits, dst, size) @@ -83,9 +108,9 @@ inet_cidr_ntop(int af, const void *src, int bits, char *dst, size_t size) { static char * inet_cidr_ntop_ipv4(const u_char *src, int bits, char *dst, size_t size) { char *odst = dst; - char *t; size_t len = 4; - int b, tb; + size_t b; + size_t bytes; if ((bits < -1) || (bits > 32)) { errno = EINVAL; @@ -94,25 +119,21 @@ inet_cidr_ntop_ipv4(const u_char *src, int bits, char *dst, size_t size) { /* Find number of significant bytes in address. */ if (bits == -1) - len = 3; + len = 4; else - for (len = 0,b = 1 ; b < 4; b++) + for (len = 1, b = 1 ; b < 4; b++) if (*(src + b)) - len = b; + len = b + 1; /* Format whole octets plus nonzero trailing octets. */ - tb = (bits <= 0) ? 1 : (bits - 1); - for (b = 0; b <= (tb / 8) || (b <= len); b++) { - if (size < sizeof "255.") - goto emsgsize; - t = dst; - dst += SPRINTF((dst, "%u", *src++)); - if (b + 1 <= (tb / 8) || (b + 1 <= len)) { - *dst++ = '.'; - *dst = '\0'; - } - size -= (size_t)(dst - t); - } + bytes = (((bits <= 0) ? 1 : bits) + 7) / 8; + if (len > bytes) + bytes = len; + b = decoct(src, bytes, dst, size); + if (b == 0) + goto emsgsize; + dst += b; + size -= b; if (bits != -1) { /* Format CIDR /width. */ @@ -127,3 +148,112 @@ inet_cidr_ntop_ipv4(const u_char *src, int bits, char *dst, size_t size) { errno = EMSGSIZE; return (NULL); } + +static char * +inet_cidr_ntop_ipv6(const u_char *src, int bits, char *dst, size_t size) { + /* + * Note that int32_t and int16_t need only be "at least" large enough + * to contain a value of the specified size. On some systems, like + * Crays, there is no such thing as an integer variable with 16 bits. + * Keep this in mind if you think this function should have been coded + * to use pointer overlays. All the world's not a VAX. + */ + char tmp[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255/128"]; + char *tp; + struct { int base, len; } best, cur; + u_int words[NS_IN6ADDRSZ / NS_INT16SZ]; + int i; + + if ((bits < -1) || (bits > 128)) { + errno = EINVAL; + return (NULL); + } + + /* + * Preprocess: + * Copy the input (bytewise) array into a wordwise array. + * Find the longest run of 0x00's in src[] for :: shorthanding. + */ + memset(words, '\0', sizeof words); + for (i = 0; i < NS_IN6ADDRSZ; i++) + words[i / 2] |= (src[i] << ((1 - (i % 2)) << 3)); + best.base = -1; + cur.base = -1; + for (i = 0; i < (NS_IN6ADDRSZ / NS_INT16SZ); i++) { + if (words[i] == 0) { + if (cur.base == -1) + cur.base = i, cur.len = 1; + else + cur.len++; + } else { + if (cur.base != -1) { + if (best.base == -1 || cur.len > best.len) + best = cur; + cur.base = -1; + } + } + } + if (cur.base != -1) { + if (best.base == -1 || cur.len > best.len) + best = cur; + } + if (best.base != -1 && best.len < 2) + best.base = -1; + + /* + * Format the result. + */ + tp = tmp; + for (i = 0; i < (NS_IN6ADDRSZ / NS_INT16SZ); i++) { + /* Are we inside the best run of 0x00's? */ + if (best.base != -1 && i >= best.base && + i < (best.base + best.len)) { + if (i == best.base) + *tp++ = ':'; + continue; + } + /* Are we following an initial run of 0x00s or any real hex? */ + if (i != 0) + *tp++ = ':'; + /* Is this address an encapsulated IPv4? */ + if (i == 6 && best.base == 0 && (best.len == 6 || + (best.len == 7 && words[7] != 0x0001) || + (best.len == 5 && words[5] == 0xffff))) { + int n; + + if (src[15] || bits == -1 || bits > 120) + n = 4; + else if (src[14] || bits > 112) + n = 3; + else + n = 2; + n = decoct(src+12, n, tp, sizeof tmp - (tp - tmp)); + if (n == 0) { + errno = EMSGSIZE; + return (NULL); + } + tp += strlen(tp); + break; + } + tp += SPRINTF((tp, "%x", words[i])); + } + + /* Was it a trailing run of 0x00's? */ + if (best.base != -1 && (best.base + best.len) == + (NS_IN6ADDRSZ / NS_INT16SZ)) + *tp++ = ':'; + *tp = '\0'; + + if (bits != -1) + tp += SPRINTF((tp, "/%u", bits)); + + /* + * Check for overflow, copy, and we're done. + */ + if ((size_t)(tp - tmp) > size) { + errno = EMSGSIZE; + return (NULL); + } + strcpy(dst, tmp); + return (dst); +} diff --git a/contrib/bind/lib/inet/inet_cidr_pton.c b/contrib/bind/lib/inet/inet_cidr_pton.c index 9ead90b..b8a7226 100644 --- a/contrib/bind/lib/inet/inet_cidr_pton.c +++ b/contrib/bind/lib/inet/inet_cidr_pton.c @@ -16,7 +16,7 @@ */ #if defined(LIBC_SCCS) && !defined(lint) -static const char rcsid[] = "$Id: inet_cidr_pton.c,v 8.4 2000/12/23 08:14:53 vixie Exp $"; +static const char rcsid[] = "$Id: inet_cidr_pton.c,v 8.7 2001/09/28 04:21:28 marka Exp $"; #endif #include "port_before.h" @@ -24,6 +24,7 @@ static const char rcsid[] = "$Id: inet_cidr_pton.c,v 8.4 2000/12/23 08:14:53 vix #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> +#include <arpa/nameser.h> #include <arpa/inet.h> #include <isc/assertions.h> @@ -42,8 +43,12 @@ static const char rcsid[] = "$Id: inet_cidr_pton.c,v 8.4 2000/12/23 08:14:53 vix #endif static int inet_cidr_pton_ipv4 __P((const char *src, u_char *dst, + int *bits, int ipv6)); +static int inet_cidr_pton_ipv6 __P((const char *src, u_char *dst, int *bits)); +static int getbits(const char *, int ipv6); + /* * int * inet_cidr_pton(af, src, dst, *bits) @@ -65,16 +70,19 @@ int inet_cidr_pton(int af, const char *src, void *dst, int *bits) { switch (af) { case AF_INET: - return (inet_cidr_pton_ipv4(src, dst, bits)); + return (inet_cidr_pton_ipv4(src, dst, bits, 0)); + case AF_INET6: + return (inet_cidr_pton_ipv6(src, dst, bits)); default: errno = EAFNOSUPPORT; return (-1); } } +static const char digits[] = "0123456789"; + static int -inet_cidr_pton_ipv4(const char *src, u_char *dst, int *pbits) { - static const char digits[] = "0123456789"; +inet_cidr_pton_ipv4(const char *src, u_char *dst, int *pbits, int ipv6) { const u_char *odst = dst; int n, ch, tmp, bits; size_t size = 4; @@ -101,30 +109,17 @@ inet_cidr_pton_ipv4(const char *src, u_char *dst, int *pbits) { /* Get the prefix length if any. */ bits = -1; - if (ch == '/' && isascii(src[0]) && isdigit(src[0]) && dst > odst) { - /* CIDR width specifier. Nothing can follow it. */ - ch = *src++; /* Skip over the /. */ - bits = 0; - do { - n = strchr(digits, ch) - digits; - INSIST(n >= 0 && n <= 9); - bits *= 10; - bits += n; - } while ((ch = *src++) != '\0' && isascii(ch) && isdigit(ch)); - if (ch != '\0') + if (ch == '/' && dst > odst) { + bits = getbits(src, ipv6); + if (bits == -2) goto enoent; - if (bits > 32) - goto emsgsize; - } - - /* Firey death and destruction unless we prefetched EOS. */ - if (ch != '\0') + } else if (ch != '\0') goto enoent; /* Prefix length can default to /32 only if all four octets spec'd. */ if (bits == -1) { if (dst - odst == 4) - bits = 32; + bits = ipv6 ? 128 : 32; else goto enoent; } @@ -134,7 +129,7 @@ inet_cidr_pton_ipv4(const char *src, u_char *dst, int *pbits) { goto enoent; /* If prefix length overspecifies mantissa, life is bad. */ - if ((bits / 8) > (dst - odst)) + if (((bits - (ipv6 ? 96 : 0)) / 8) > (dst - odst)) goto enoent; /* Extend address to four octets. */ @@ -152,3 +147,129 @@ inet_cidr_pton_ipv4(const char *src, u_char *dst, int *pbits) { errno = EMSGSIZE; return (-1); } + +static int +inet_cidr_pton_ipv6(const char *src, u_char *dst, int *pbits) { + static const char xdigits_l[] = "0123456789abcdef", + xdigits_u[] = "0123456789ABCDEF"; + u_char tmp[NS_IN6ADDRSZ], *tp, *endp, *colonp; + const char *xdigits, *curtok; + int ch, saw_xdigit; + u_int val; + int bits; + + memset((tp = tmp), '\0', NS_IN6ADDRSZ); + endp = tp + NS_IN6ADDRSZ; + colonp = NULL; + /* Leading :: requires some special handling. */ + if (*src == ':') + if (*++src != ':') + return (0); + curtok = src; + saw_xdigit = 0; + val = 0; + bits = -1; + while ((ch = *src++) != '\0') { + const char *pch; + + if ((pch = strchr((xdigits = xdigits_l), ch)) == NULL) + pch = strchr((xdigits = xdigits_u), ch); + if (pch != NULL) { + val <<= 4; + val |= (pch - xdigits); + if (val > 0xffff) + return (0); + saw_xdigit = 1; + continue; + } + if (ch == ':') { + curtok = src; + if (!saw_xdigit) { + if (colonp) + return (0); + colonp = tp; + continue; + } else if (*src == '\0') { + return (0); + } + if (tp + NS_INT16SZ > endp) + return (0); + *tp++ = (u_char) (val >> 8) & 0xff; + *tp++ = (u_char) val & 0xff; + saw_xdigit = 0; + val = 0; + continue; + } + if (ch == '.' && ((tp + NS_INADDRSZ) <= endp) && + inet_cidr_pton_ipv4(curtok, tp, &bits, 1) == 0) { + tp += NS_INADDRSZ; + saw_xdigit = 0; + break; /* '\0' was seen by inet_pton4(). */ + } + if (ch == '/') { + bits = getbits(src, 1); + if (bits == -2) + goto enoent; + break; + } + goto enoent; + } + if (saw_xdigit) { + if (tp + NS_INT16SZ > endp) + goto emsgsize; + *tp++ = (u_char) (val >> 8) & 0xff; + *tp++ = (u_char) val & 0xff; + } + if (colonp != NULL) { + /* + * Since some memmove()'s erroneously fail to handle + * overlapping regions, we'll do the shift by hand. + */ + const int n = tp - colonp; + int i; + + if (tp == endp) + goto enoent; + for (i = 1; i <= n; i++) { + endp[- i] = colonp[n - i]; + colonp[n - i] = 0; + } + tp = endp; + } + + memcpy(dst, tmp, NS_IN6ADDRSZ); + + *pbits = bits; + return (0); + + enoent: + errno = ENOENT; + return (-1); + + emsgsize: + errno = EMSGSIZE; + return (-1); +} + +int +getbits(const char *src, int ipv6) { + int bits = 0; + char *cp, ch; + + if (*src == '\0') /* syntax */ + return (-2); + do { + ch = *src++; + cp = strchr(digits, ch); + if (cp == NULL) /* syntax */ + return (-2); + bits *= 10; + bits += cp - digits; + if (bits == 0 && *src != '\0') /* no leading zeros */ + return (-2); + if (bits > (ipv6 ? 128 : 32)) /* range error */ + return (-2); + } while (*src != '\0'); + + return (bits); +} diff --git a/contrib/bind/lib/inet/inet_data.c b/contrib/bind/lib/inet/inet_data.c new file mode 100644 index 0000000..47b6d9b --- /dev/null +++ b/contrib/bind/lib/inet/inet_data.c @@ -0,0 +1,44 @@ +/* + * Copyright (c) 1995-1999 by Internet Software Consortium. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS + * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE + * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS + * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + * SOFTWARE. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char rcsid[] = "$Id: inet_data.c,v 1.2 2001/06/20 22:06:36 marka Exp $"; +#endif /* LIBC_SCCS and not lint */ + +#include "port_before.h" + +#include <sys/types.h> +#include <sys/param.h> +#include <sys/socket.h> +#include <sys/time.h> + +#include <netinet/in.h> +#include <arpa/inet.h> +#include <arpa/nameser.h> + +#include <ctype.h> +#include <netdb.h> +#include <resolv.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#include "port_after.h" + +const struct in6_addr isc_in6addr_any = IN6ADDR_ANY_INIT; +const struct in6_addr isc_in6addr_loopback = IN6ADDR_LOOPBACK_INIT; diff --git a/contrib/bind/lib/inet/inet_net_ntop.c b/contrib/bind/lib/inet/inet_net_ntop.c index d8b8377..b38a6ca 100644 --- a/contrib/bind/lib/inet/inet_net_ntop.c +++ b/contrib/bind/lib/inet/inet_net_ntop.c @@ -16,7 +16,7 @@ */ #if defined(LIBC_SCCS) && !defined(lint) -static const char rcsid[] = "$Id: inet_net_ntop.c,v 1.7 2001/01/25 19:55:59 vixie Exp $"; +static const char rcsid[] = "$Id: inet_net_ntop.c,v 1.8 2001/09/27 15:08:36 marka Exp $"; #endif #include "port_before.h" @@ -41,6 +41,8 @@ static const char rcsid[] = "$Id: inet_net_ntop.c,v 1.7 2001/01/25 19:55:59 vixi static char * inet_net_ntop_ipv4 __P((const u_char *src, int bits, char *dst, size_t size)); +static char * inet_net_ntop_ipv6 __P((const u_char *src, int bits, + char *dst, size_t size)); /* * char * @@ -63,6 +65,8 @@ inet_net_ntop(af, src, bits, dst, size) switch (af) { case AF_INET: return (inet_net_ntop_ipv4(src, bits, dst, size)); + case AF_INET6: + return (inet_net_ntop_ipv6(src, bits, dst, size)); default: errno = EAFNOSUPPORT; return (NULL); @@ -98,6 +102,7 @@ inet_net_ntop_ipv4(src, bits, dst, size) errno = EINVAL; return (NULL); } + if (bits == 0) { if (size < sizeof "0") goto emsgsize; @@ -142,3 +147,131 @@ inet_net_ntop_ipv4(src, bits, dst, size) errno = EMSGSIZE; return (NULL); } + +/* + * static char * + * inet_net_ntop_ipv6(src, bits, fakebits, dst, size) + * convert IPv6 network number from network to presentation format. + * generates CIDR style result always. Picks the shortest representation + * unless the IP is really IPv4. + * always prints specified number of bits (bits). + * return: + * pointer to dst, or NULL if an error occurred (check errno). + * note: + * network byte order assumed. this means 192.5.5.240/28 has + * 0x11110000 in its fourth octet. + * author: + * Vadim Kogan (UCB), June 2001 + * Original version (IPv4) by Paul Vixie (ISC), July 1996 + */ + +static char * +inet_net_ntop_ipv6(const u_char *src, int bits, char *dst, size_t size) { + u_int m; + int b; + int p; + int zero_s, zero_l, tmp_zero_s, tmp_zero_l; + int i; + int is_ipv4 = 0; + unsigned char inbuf[16]; + char outbuf[sizeof("xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:255.255.255.255/128")]; + char *cp; + int words; + u_char *s; + + if (bits < 0 || bits > 128) { + errno = EINVAL; + return (NULL); + } + + cp = outbuf; + + if (bits == 0) { + *cp++ = ':'; + *cp++ = ':'; + *cp = '\0'; + } else { + /* Copy src to private buffer. Zero host part. */ + p = (bits + 7) / 8; + memcpy(inbuf, src, p); + memset(inbuf + p, 0, 16 - p); + b = bits % 8; + if (b != 0) { + m = ~0 << (8 - b); + inbuf[p-1] &= m; + } + + s = inbuf; + + /* how many words need to be displayed in output */ + words = (bits + 15) / 16; + if (words == 1) + words = 2; + + /* Find the longest substring of zero's */ + zero_s = zero_l = tmp_zero_s = tmp_zero_l = 0; + for (i = 0; i < (words * 2); i += 2) { + if ((s[i] | s[i+1]) == 0) { + if (tmp_zero_l == 0) + tmp_zero_s = i / 2; + tmp_zero_l++; + } else { + if (tmp_zero_l && zero_l < tmp_zero_l) { + zero_s = tmp_zero_s; + zero_l = tmp_zero_l; + tmp_zero_l = 0; + } + } + } + + if (tmp_zero_l && zero_l < tmp_zero_l) { + zero_s = tmp_zero_s; + zero_l = tmp_zero_l; + } + + if (zero_l != words && zero_s == 0 && ((zero_l == 6) || + ((zero_l == 5 && s[10] == 0xff && s[11] == 0xff) || + ((zero_l == 7 && s[14] != 0 && s[15] != 1))))) + is_ipv4 = 1; + + /* Format whole words. */ + for (p = 0; p < words; p++) { + if (zero_l != 0 && p >= zero_s && p < zero_s + zero_l) { + /* Time to skip some zeros */ + if (p == zero_s) + *cp++ = ':'; + if (p == words - 1) + *cp++ = ':'; + s++; + s++; + continue; + } + + if (is_ipv4 && p > 5 ) { + *cp++ = (p == 6) ? ':' : '.'; + cp += SPRINTF((cp, "%u", *s++)); + /* we can potentially drop the last octet */ + if (p != 7 || bits > 120) { + *cp++ = '.'; + cp += SPRINTF((cp, "%u", *s++)); + } + } else { + if (cp != outbuf) + *cp++ = ':'; + cp += SPRINTF((cp, "%x", *s * 256 + s[1])); + s += 2; + } + } + } + /* Format CIDR /width. */ + SPRINTF((cp, "/%u", bits)); + if (strlen(outbuf) + 1 > size) + goto emsgsize; + strcpy(dst, outbuf); + + return (dst); + +emsgsize: + errno = EMSGSIZE; + return (NULL); +} diff --git a/contrib/bind/lib/inet/inet_net_pton.c b/contrib/bind/lib/inet/inet_net_pton.c index 4d265b2..ff62a8b 100644 --- a/contrib/bind/lib/inet/inet_net_pton.c +++ b/contrib/bind/lib/inet/inet_net_pton.c @@ -16,7 +16,7 @@ */ #if defined(LIBC_SCCS) && !defined(lint) -static const char rcsid[] = "$Id: inet_net_pton.c,v 1.11 1999/01/08 19:23:44 vixie Exp $"; +static const char rcsid[] = "$Id: inet_net_pton.c,v 1.13 2001/09/27 15:08:38 marka Exp $"; #endif #include "port_before.h" @@ -24,6 +24,7 @@ static const char rcsid[] = "$Id: inet_net_pton.c,v 1.11 1999/01/08 19:23:44 vix #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> +#include <arpa/nameser.h> #include <arpa/inet.h> #include <isc/assertions.h> @@ -41,38 +42,6 @@ static const char rcsid[] = "$Id: inet_net_pton.c,v 1.11 1999/01/08 19:23:44 vix # define SPRINTF(x) ((size_t)sprintf x) #endif -static int inet_net_pton_ipv4 __P((const char *src, u_char *dst, - size_t size)); - -/* - * static int - * inet_net_pton(af, src, dst, size) - * convert network number from presentation to network format. - * accepts hex octets, hex strings, decimal octets, and /CIDR. - * "size" is in bytes and describes "dst". - * return: - * number of bits, either imputed classfully or specified with /CIDR, - * or -1 if some failure occurred (check errno). ENOENT means it was - * not a valid network specification. - * author: - * Paul Vixie (ISC), June 1996 - */ -int -inet_net_pton(af, src, dst, size) - int af; - const char *src; - void *dst; - size_t size; -{ - switch (af) { - case AF_INET: - return (inet_net_pton_ipv4(src, dst, size)); - default: - errno = EAFNOSUPPORT; - return (-1); - } -} - /* * static int * inet_net_pton_ipv4(src, dst, size) @@ -90,20 +59,16 @@ inet_net_pton(af, src, dst, size) * Paul Vixie (ISC), June 1996 */ static int -inet_net_pton_ipv4(src, dst, size) - const char *src; - u_char *dst; - size_t size; -{ - static const char - xdigits[] = "0123456789abcdef", - digits[] = "0123456789"; - int n, ch, tmp, dirty, bits; +inet_net_pton_ipv4( const char *src, u_char *dst, size_t size) { + static const char xdigits[] = "0123456789abcdef"; + static const char digits[] = "0123456789"; + int n, ch, tmp = 0, dirty, bits; const u_char *odst = dst; ch = *src++; if (ch == '0' && (src[0] == 'x' || src[0] == 'X') - && isascii(src[1]) && isxdigit(src[1])) { + && isascii((unsigned char)(src[1])) + && isxdigit((unsigned char)(src[1]))) { /* Hexadecimal: Eat nybble string. */ if (size <= 0) goto emsgsize; @@ -158,7 +123,8 @@ inet_net_pton_ipv4(src, dst, size) goto enoent; bits = -1; - if (ch == '/' && isascii(src[0]) && isdigit(src[0]) && dst > odst) { + if (ch == '/' && isascii((unsigned char)(src[0])) && + isdigit((unsigned char)(src[0])) && dst > odst) { /* CIDR width specifier. Nothing can follow it. */ ch = *src++; /* Skip over the /. */ bits = 0; @@ -213,3 +179,221 @@ inet_net_pton_ipv4(src, dst, size) errno = EMSGSIZE; return (-1); } + +static int +getbits(const char *src, int *bitsp) { + static const char digits[] = "0123456789"; + int n; + int val; + char ch; + + val = 0; + n = 0; + while ((ch = *src++) != '\0') { + const char *pch; + + pch = strchr(digits, ch); + if (pch != NULL) { + if (n++ != 0 && val == 0) /* no leading zeros */ + return (0); + val *= 10; + val += (pch - digits); + if (val > 128) /* range */ + return (0); + continue; + } + return (0); + } + if (n == 0) + return (0); + *bitsp = val; + return (1); +} + +static int +getv4(const char *src, u_char *dst, int *bitsp) { + static const char digits[] = "0123456789"; + u_char *odst = dst; + int n; + u_int val; + char ch; + + val = 0; + n = 0; + while ((ch = *src++) != '\0') { + const char *pch; + + pch = strchr(digits, ch); + if (pch != NULL) { + if (n++ != 0 && val == 0) /* no leading zeros */ + return (0); + val *= 10; + val += (pch - digits); + if (val > 255) /* range */ + return (0); + continue; + } + if (ch == '.' || ch == '/') { + if (dst - odst > 3) /* too many octets? */ + return (0); + *dst++ = val; + if (ch == '/') + return (getbits(src, bitsp)); + val = 0; + n = 0; + continue; + } + return (0); + } + if (n == 0) + return (0); + if (dst - odst > 3) /* too many octets? */ + return (0); + *dst++ = val; + return (1); +} + +static int +inet_net_pton_ipv6(const char *src, u_char *dst, size_t size) { + static const char xdigits_l[] = "0123456789abcdef", + xdigits_u[] = "0123456789ABCDEF"; + u_char tmp[NS_IN6ADDRSZ], *tp, *endp, *colonp; + const char *xdigits, *curtok; + int ch, saw_xdigit; + u_int val; + int digits; + int bits; + size_t bytes; + int words; + int ipv4; + + memset((tp = tmp), '\0', NS_IN6ADDRSZ); + endp = tp + NS_IN6ADDRSZ; + colonp = NULL; + /* Leading :: requires some special handling. */ + if (*src == ':') + if (*++src != ':') + goto enoent; + curtok = src; + saw_xdigit = 0; + val = 0; + digits = 0; + bits = -1; + ipv4 = 0; + while ((ch = *src++) != '\0') { + const char *pch; + + if ((pch = strchr((xdigits = xdigits_l), ch)) == NULL) + pch = strchr((xdigits = xdigits_u), ch); + if (pch != NULL) { + val <<= 4; + val |= (pch - xdigits); + if (++digits > 4) + goto enoent; + saw_xdigit = 1; + continue; + } + if (ch == ':') { + curtok = src; + if (!saw_xdigit) { + if (colonp) + goto enoent; + colonp = tp; + continue; + } else if (*src == '\0') + goto enoent; + if (tp + NS_INT16SZ > endp) + return (0); + *tp++ = (u_char) (val >> 8) & 0xff; + *tp++ = (u_char) val & 0xff; + saw_xdigit = 0; + digits = 0; + val = 0; + continue; + } + if (ch == '.' && ((tp + NS_INADDRSZ) <= endp) && + getv4(curtok, tp, &bits) > 0) { + tp += NS_INADDRSZ; + saw_xdigit = 0; + ipv4 = 1; + break; /* '\0' was seen by inet_pton4(). */ + } + if (ch == '/' && getbits(src, &bits) > 0) + break; + goto enoent; + } + if (saw_xdigit) { + if (tp + NS_INT16SZ > endp) + goto enoent; + *tp++ = (u_char) (val >> 8) & 0xff; + *tp++ = (u_char) val & 0xff; + } + if (bits == -1) + bits = 128; + + words = (bits + 15) / 16; + if (words < 2) + words = 2; + if (ipv4) + words = 8; + endp = tmp + 2 * words; + + if (colonp != NULL) { + /* + * Since some memmove()'s erroneously fail to handle + * overlapping regions, we'll do the shift by hand. + */ + const int n = tp - colonp; + int i; + + if (tp == endp) + goto enoent; + for (i = 1; i <= n; i++) { + endp[- i] = colonp[n - i]; + colonp[n - i] = 0; + } + tp = endp; + } + if (tp != endp) + goto enoent; + + bytes = (bits + 7) / 8; + if (bytes > size) + goto emsgsize; + memcpy(dst, tmp, bytes); + return (bits); + + enoent: + errno = ENOENT; + return (-1); + + emsgsize: + errno = EMSGSIZE; + return (-1); +} + +/* + * int + * inet_net_pton(af, src, dst, size) + * convert network number from presentation to network format. + * accepts hex octets, hex strings, decimal octets, and /CIDR. + * "size" is in bytes and describes "dst". + * return: + * number of bits, either imputed classfully or specified with /CIDR, + * or -1 if some failure occurred (check errno). ENOENT means it was + * not a valid network specification. + * author: + * Paul Vixie (ISC), June 1996 + */ +int +inet_net_pton(int af, const char *src, void *dst, size_t size) { + switch (af) { + case AF_INET: + return (inet_net_pton_ipv4(src, dst, size)); + case AF_INET6: + return (inet_net_pton_ipv6(src, dst, size)); + default: + errno = EAFNOSUPPORT; + return (-1); + } +} diff --git a/contrib/bind/lib/inet/inet_network.c b/contrib/bind/lib/inet/inet_network.c index d26369c..9090d13 100644 --- a/contrib/bind/lib/inet/inet_network.c +++ b/contrib/bind/lib/inet/inet_network.c @@ -65,7 +65,7 @@ again: if (*cp == 'x' || *cp == 'X') base = 16, cp++; while ((c = *cp) != 0) { - if (isdigit(c)) { + if (isdigit((unsigned char)c)) { if (base == 8 && (c == '8' || c == '9')) return (INADDR_NONE); val = (val * base) + (c - '0'); @@ -73,8 +73,9 @@ again: digit = 1; continue; } - if (base == 16 && isxdigit(c)) { - val = (val << 4) + (c + 10 - (islower(c) ? 'a' : 'A')); + if (base == 16 && isxdigit((unsigned char)c)) { + val = (val << 4) + + (c + 10 - (islower((unsigned char)c) ? 'a' : 'A')); cp++; digit = 1; continue; @@ -89,7 +90,7 @@ again: *pp++ = val, cp++; goto again; } - if (*cp && !isspace(*cp)) + if (*cp && !isspace(*cp&0xff)) return (INADDR_NONE); *pp++ = val; n = pp - parts; diff --git a/contrib/bind/lib/inet/inet_ntop.c b/contrib/bind/lib/inet/inet_ntop.c index d588e9f..e05812e 100644 --- a/contrib/bind/lib/inet/inet_ntop.c +++ b/contrib/bind/lib/inet/inet_ntop.c @@ -16,7 +16,7 @@ */ #if defined(LIBC_SCCS) && !defined(lint) -static const char rcsid[] = "$Id: inet_ntop.c,v 1.10 2001/01/25 20:21:10 vixie Exp $"; +static const char rcsid[] = "$Id: inet_ntop.c,v 1.11 2001/09/27 15:12:57 marka Exp $"; #endif /* LIBC_SCCS and not lint */ #include "port_before.h" @@ -175,8 +175,9 @@ inet_ntop6(src, dst, size) if (i != 0) *tp++ = ':'; /* Is this address an encapsulated IPv4? */ - if (i == 6 && best.base == 0 && - (best.len == 6 || (best.len == 5 && words[5] == 0xffff))) { + if (i == 6 && best.base == 0 && (best.len == 6 || + (best.len == 7 && words[7] != 0x0001) || + (best.len == 5 && words[5] == 0xffff))) { if (!inet_ntop4(src+12, tp, sizeof tmp - (tp - tmp))) return (NULL); tp += strlen(tp); diff --git a/contrib/bind/lib/inet/inet_pton.c b/contrib/bind/lib/inet/inet_pton.c index 0a2927d..a6b0a71 100644 --- a/contrib/bind/lib/inet/inet_pton.c +++ b/contrib/bind/lib/inet/inet_pton.c @@ -16,7 +16,7 @@ */ #if defined(LIBC_SCCS) && !defined(lint) -static const char rcsid[] = "$Id: inet_pton.c,v 1.7 1999/10/13 16:39:28 vixie Exp $"; +static const char rcsid[] = "$Id: inet_pton.c,v 1.8 2001/07/16 03:22:24 marka Exp $"; #endif /* LIBC_SCCS and not lint */ #include "port_before.h" @@ -95,10 +95,12 @@ inet_pton4(src, dst) if ((pch = strchr(digits, ch)) != NULL) { u_int new = *tp * 10 + (pch - digits); + if (saw_digit && *tp == 0) + return (0); if (new > 255) return (0); *tp = new; - if (! saw_digit) { + if (!saw_digit) { if (++octets > 4) return (0); saw_digit = 1; diff --git a/contrib/bind/lib/inet/nsap_addr.c b/contrib/bind/lib/inet/nsap_addr.c index da388dc..7198b9d 100644 --- a/contrib/bind/lib/inet/nsap_addr.c +++ b/contrib/bind/lib/inet/nsap_addr.c @@ -16,7 +16,7 @@ */ #if defined(LIBC_SCCS) && !defined(lint) -static const char rcsid[] = "$Id: nsap_addr.c,v 8.11 2001/03/26 07:04:30 marka Exp $"; +static const char rcsid[] = "$Id: nsap_addr.c,v 8.12 2001/05/28 07:37:46 marka Exp $"; #endif /* LIBC_SCCS and not lint */ #include "port_before.h" @@ -46,6 +46,7 @@ inet_nsap_addr(const char *ascii, u_char *binary, int maxlen) { if (ascii[0] != '0' || (ascii[1] != 'x' && ascii[1] != 'X')) return (0); + ascii += 2; while ((c = *ascii++) != '\0' && len < (u_int)maxlen) { if (c == '.' || c == '+' || c == '/') @@ -88,8 +89,8 @@ inet_nsap_ntoa(int binlen, const u_char *binary, char *ascii) { start = tmpbuf; } - *ascii = '0'; - *ascii = 'x'; + *ascii++ = '0'; + *ascii++ = 'x'; if (binlen > 255) binlen = 255; diff --git a/contrib/bind/lib/irs/Makefile b/contrib/bind/lib/irs/Makefile index 4784ccf..0c4e46d 100644 --- a/contrib/bind/lib/irs/Makefile +++ b/contrib/bind/lib/irs/Makefile @@ -13,7 +13,7 @@ # ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS # SOFTWARE. -# $Id: Makefile,v 8.21 2000/12/23 08:02:59 vixie Exp $ +# $Id: Makefile,v 8.24 2001/08/14 05:58:07 marka Exp $ # these are only appropriate for BSD 4.4 or derivatives, and are used in # development. normal builds will be done in the top level directory and @@ -83,7 +83,7 @@ ${LIBBIND}: ${OBJS} ${RANLIB} ${LIBBIND} .c.${O}: - if test ! -d ${THREADED} ; then mkdir ${THREADED} ; else true ; fi + mkdir ${THREADED} 2> /dev/null || test -d ${THREADED} -a -w ${THREADED} -(${CC} ${CPPFLAGS} ${CFLAGS} ${BOUNDS} ${REENTRANT} -c $*.c \ -o ${THREADED}/$*.${O} ; \ ${LDS} ${LD} ${LD_LIBFLAGS} ${THREADED}/$*.${O} \ diff --git a/contrib/bind/lib/irs/dns.c b/contrib/bind/lib/irs/dns.c index 66bdbf5..3feed26 100644 --- a/contrib/bind/lib/irs/dns.c +++ b/contrib/bind/lib/irs/dns.c @@ -16,7 +16,7 @@ */ #if defined(LIBC_SCCS) && !defined(lint) -static const char rcsid[] = "$Id: dns.c,v 1.15 2000/02/28 07:52:16 vixie Exp $"; +static const char rcsid[] = "$Id: dns.c,v 1.16 2001/05/29 05:48:26 marka Exp $"; #endif /* @@ -59,6 +59,8 @@ irs_dns_acc(const char *options) { struct irs_acc *acc; struct dns_p *dns; + UNUSED(options); + if (!(acc = memget(sizeof *acc))) { errno = ENOMEM; return (NULL); diff --git a/contrib/bind/lib/irs/dns_gr.c b/contrib/bind/lib/irs/dns_gr.c index 64cbe9b..a622345 100644 --- a/contrib/bind/lib/irs/dns_gr.c +++ b/contrib/bind/lib/irs/dns_gr.c @@ -16,7 +16,7 @@ */ #if defined(LIBC_SCCS) && !defined(lint) -static const char rcsid[] = "$Id: dns_gr.c,v 1.19 1999/01/18 07:46:48 vixie Exp $"; +static const char rcsid[] = "$Id: dns_gr.c,v 1.20 2001/05/29 05:48:27 marka Exp $"; #endif /* @@ -146,6 +146,9 @@ gr_close(struct irs_gr *this) { static struct group * gr_next(struct irs_gr *this) { + + UNUSED(this); + return (NULL); } @@ -164,6 +167,9 @@ gr_bygid(struct irs_gr *this, gid_t gid) { static void gr_rewind(struct irs_gr *this) { + + UNUSED(this); + /* NOOP */ } @@ -171,6 +177,11 @@ static int gr_list(struct irs_gr *this, const char *name, gid_t basegid, gid_t *groups, int *ngroups) { + UNUSED(this); + UNUSED(name); + UNUSED(basegid); + UNUSED(groups); + *ngroups = 0; /* There's some way to do this in Hesiod. */ return (-1); @@ -178,6 +189,8 @@ gr_list(struct irs_gr *this, const char *name, static void gr_minimize(struct irs_gr *this) { + + UNUSED(this); /* NOOP */ } diff --git a/contrib/bind/lib/irs/dns_ho.c b/contrib/bind/lib/irs/dns_ho.c index 8b2df77..e340f02 100644 --- a/contrib/bind/lib/irs/dns_ho.c +++ b/contrib/bind/lib/irs/dns_ho.c @@ -52,7 +52,7 @@ /* BIND Id: gethnamaddr.c,v 8.15 1996/05/22 04:56:30 vixie Exp $ */ #if defined(LIBC_SCCS) && !defined(lint) -static const char rcsid[] = "$Id: dns_ho.c,v 1.28 2000/04/20 07:47:54 vixie Exp $"; +static const char rcsid[] = "$Id: dns_ho.c,v 1.33 2001/10/05 04:30:21 marka Exp $"; #endif /* LIBC_SCCS and not lint */ /* Imports. */ @@ -94,11 +94,7 @@ static const char rcsid[] = "$Id: dns_ho.c,v 1.28 2000/04/20 07:47:54 vixie Exp #define MAXALIASES 35 #define MAXADDRS 35 -#if PACKETSZ > 1024 -#define MAXPACKET PACKETSZ -#else -#define MAXPACKET 1024 -#endif +#define MAXPACKET (1024*64) #define BOUNDS_CHECK(ptr, count) \ if ((ptr) + (count) > eom) { \ @@ -106,6 +102,26 @@ static const char rcsid[] = "$Id: dns_ho.c,v 1.28 2000/04/20 07:47:54 vixie Exp continue; \ } else (void)0 +typedef union { + HEADER hdr; + u_char buf[MAXPACKET]; +} querybuf; + +struct dns_res_target { + struct dns_res_target *next; + querybuf qbuf; /* query buffer */ + u_char *answer; /* buffer to put answer */ + int anslen; /* size of answer buffer */ + int qclass, qtype; /* class and type of query */ + int action; /* condition whether query is really issued */ + char qname[MAXDNAME +1]; /* domain name */ +#if 0 + int n; /* result length */ +#endif +}; +enum {RESTGT_DOALWAYS, RESTGT_AFTERFAILURE, RESTGT_IGNORE}; +enum {RESQRY_SUCCESS, RESQRY_FAIL}; + struct pvt { struct hostent host; char * h_addr_ptrs[MAXADDRS + 1]; @@ -141,6 +157,8 @@ static struct __res_state * ho_res_get(struct irs_ho *this); static void ho_res_set(struct irs_ho *this, struct __res_state *res, void (*free_res)(void *)); +static struct addrinfo * ho_addrinfo(struct irs_ho *this, const char *name, + const struct addrinfo *pai); static void map_v4v6_hostent(struct hostent *hp, char **bp, int *len); @@ -148,7 +166,20 @@ static void addrsort(res_state, char **, int); static struct hostent * gethostans(struct irs_ho *this, const u_char *ansbuf, int anslen, const char *qname, int qtype, - int af, int size); + int af, int size, + struct addrinfo **ret_aip, + const struct addrinfo *pai); +static int add_hostent(struct pvt *pvt, char *bp, char **hap, + struct addrinfo *ai); +static const u_char * ar_head(const u_char *, int, const u_char *, + const u_char *, struct pvt *, + int (*)(const char *)); +static struct addrinfo * a6_expand(const u_char *, const u_char *, int, + const u_char *, const u_char *, + const struct in6_addr *, int, + const struct addrinfo *, + struct pvt *, int (*)(const char *), int *); +static const char *dname_subst(const char *, const char *, const char *); static int init(struct irs_ho *this); /* Exports. */ @@ -158,6 +189,8 @@ irs_dns_ho(struct irs_acc *this) { struct irs_ho *ho; struct pvt *pvt; + UNUSED(this); + if (!(pvt = memget(sizeof *pvt))) { errno = ENOMEM; return (NULL); @@ -180,6 +213,7 @@ irs_dns_ho(struct irs_acc *this) { ho->minimize = ho_minimize; ho->res_get = ho_res_get; ho->res_set = ho_res_set; + ho->addrinfo = ho_addrinfo; return (ho); } @@ -214,24 +248,50 @@ ho_byname(struct irs_ho *this, const char *name) { } static struct hostent * -ho_byname2(struct irs_ho *this, const char *name, int af) { +ho_byname2(struct irs_ho *this, const char *name, int af) +{ struct pvt *pvt = (struct pvt *)this->private; - int n, size, type; - u_char buf[MAXPACKET]; + struct hostent *hp = NULL; + int n, size; char tmp[NS_MAXDNAME]; const char *cp; + struct addrinfo ai; + struct dns_res_target q, q2, *p; + int querystate = RESQRY_FAIL; if (init(this) == -1) return (NULL); + memset(&q, 0, sizeof(q2)); + memset(&q2, 0, sizeof(q2)); + switch (af) { case AF_INET: size = INADDRSZ; - type = T_A; + q.qclass = C_IN; + q.qtype = T_A; + q.answer = q.qbuf.buf; + q.anslen = sizeof(q.qbuf); + q.action = RESTGT_DOALWAYS; break; case AF_INET6: size = IN6ADDRSZ; - type = T_AAAA; + q.qclass = C_IN; + q.qtype = ns_t_a6; + q.answer = q.qbuf.buf; + q.anslen = sizeof(q.qbuf); + q.next = &q2; +#ifdef RES_USE_A6 + if ((pvt->res->options & RES_USE_A6) == 0) + q.action = RESTGT_IGNORE; + else +#endif + q.action = RESTGT_DOALWAYS; + q2.qclass = C_IN; + q2.qtype = T_AAAA; + q2.answer = q2.qbuf.buf; + q2.anslen = sizeof(q2.qbuf); + q2.action = RESTGT_AFTERFAILURE; break; default: RES_SET_H_ERRNO(pvt->res, NETDB_INTERNAL); @@ -248,30 +308,62 @@ ho_byname2(struct irs_ho *this, const char *name, int af) { tmp, sizeof tmp))) name = cp; - if ((n = res_nsearch(pvt->res, name, C_IN, type, - buf, sizeof buf)) < 0) - return (NULL); - return (gethostans(this, buf, n, name, type, af, size)); + for (p = &q; p; p = p->next) { + switch(p->action) { + case RESTGT_DOALWAYS: + break; + case RESTGT_AFTERFAILURE: + if (querystate == RESQRY_SUCCESS) + continue; + break; + case RESTGT_IGNORE: + continue; + } + + if ((n = res_nsearch(pvt->res, name, p->qclass, p->qtype, + p->answer, p->anslen)) < 0) { + querystate = RESQRY_FAIL; + continue; + } + + memset(&ai, 0, sizeof(ai)); + ai.ai_family = af; + if ((hp = gethostans(this, p->answer, n, name, p->qtype, + af, size, NULL, + (const struct addrinfo *)&ai)) != NULL) + return(hp); /* no more loop is necessary */ + + querystate = RESQRY_FAIL; + continue; + } + + return(hp); /* should be NULL */ } static struct hostent * -ho_byaddr(struct irs_ho *this, const void *addr, int len, int af) { +ho_byaddr(struct irs_ho *this, const void *addr, int len, int af) +{ struct pvt *pvt = (struct pvt *)this->private; const u_char *uaddr = addr; - char qbuf[MAXDNAME+1], *qp; - u_char buf[MAXPACKET]; + char *qp; struct hostent *hp; + struct addrinfo ai; + struct dns_res_target q, q2, *p; int n, size; + int querystate = RESQRY_FAIL; if (init(this) == -1) return (NULL); + memset(&q, 0, sizeof(q2)); + memset(&q2, 0, sizeof(q2)); + if (af == AF_INET6 && len == IN6ADDRSZ && (!memcmp(uaddr, mapped, sizeof mapped) || (!memcmp(uaddr, tunnelled, sizeof tunnelled) && memcmp(&uaddr[sizeof tunnelled], v6local, sizeof(v6local))))) { /* Unmap. */ - addr = (char *)addr + sizeof mapped; + addr = (const char *)addr + sizeof mapped; uaddr += sizeof mapped; af = AF_INET; len = INADDRSZ; @@ -279,9 +371,31 @@ ho_byaddr(struct irs_ho *this, const void *addr, int len, int af) { switch (af) { case AF_INET: size = INADDRSZ; + q.qclass = C_IN; + q.qtype = T_PTR; + q.answer = q.qbuf.buf; + q.anslen = sizeof(q.qbuf); + q.action = RESTGT_DOALWAYS; break; case AF_INET6: size = IN6ADDRSZ; + q.qclass = C_IN; + q.qtype = T_PTR; + q.answer = q.qbuf.buf; + q.anslen = sizeof(q.qbuf); + q.next = &q2; + if ((pvt->res->options & RES_NO_BITSTRING) != 0) + q.action = RESTGT_IGNORE; + else + q.action = RESTGT_DOALWAYS; + q2.qclass = C_IN; + q2.qtype = T_PTR; + q2.answer = q2.qbuf.buf; + q2.anslen = sizeof(q2.qbuf); + if ((pvt->res->options & RES_NO_NIBBLE) != 0) + q2.action = RESTGT_IGNORE; + else + q2.action = RESTGT_AFTERFAILURE; break; default: errno = EAFNOSUPPORT; @@ -295,49 +409,93 @@ ho_byaddr(struct irs_ho *this, const void *addr, int len, int af) { } switch (af) { case AF_INET: - (void) sprintf(qbuf, "%u.%u.%u.%u.in-addr.arpa", + qp = q.qname; + (void) sprintf(qp, "%u.%u.%u.%u.in-addr.arpa", (uaddr[3] & 0xff), (uaddr[2] & 0xff), (uaddr[1] & 0xff), (uaddr[0] & 0xff)); break; case AF_INET6: - qp = qbuf; - for (n = IN6ADDRSZ - 1; n >= 0; n--) { - qp += SPRINTF((qp, "%x.%x.", - uaddr[n] & 0xf, - (uaddr[n] >> 4) & 0xf)); + if (q.action != RESTGT_IGNORE) { + qp = q.qname; + qp += SPRINTF((qp, "\\[x")); + for (n = 0; n < IN6ADDRSZ; n++) + qp += SPRINTF((qp, "%02x", uaddr[n])); + SPRINTF((qp, "/128].%s", + res_get_bitstringsuffix(pvt->res))); + } + if (q2.action != RESTGT_IGNORE) { + qp = q2.qname; + for (n = IN6ADDRSZ - 1; n >= 0; n--) { + qp += SPRINTF((qp, "%x.%x.", + uaddr[n] & 0xf, + (uaddr[n] >> 4) & 0xf)); + } + strcpy(qp, res_get_nibblesuffix(pvt->res)); } - strcpy(qp, "ip6.int"); break; default: abort(); } - n = res_nquery(pvt->res, qbuf, C_IN, T_PTR, buf, sizeof buf); - if (n < 0) - return (NULL); - hp = gethostans(this, buf, n, qbuf, T_PTR, af, size); - if (!hp) - return (NULL); /* H_ERRNO was set by gethostans() */ - memcpy(pvt->host_addr, addr, len); - pvt->h_addr_ptrs[0] = (char *)pvt->host_addr; - pvt->h_addr_ptrs[1] = NULL; - if (af == AF_INET && (pvt->res->options & RES_USE_INET6)) { - map_v4v6_address((char*)pvt->host_addr, (char*)pvt->host_addr); - pvt->host.h_addrtype = AF_INET6; - pvt->host.h_length = IN6ADDRSZ; - } - RES_SET_H_ERRNO(pvt->res, NETDB_SUCCESS); - return (hp); + + for (p = &q; p; p = p->next) { + switch(p->action) { + case RESTGT_DOALWAYS: + break; + case RESTGT_AFTERFAILURE: + if (querystate == RESQRY_SUCCESS) + continue; + break; + case RESTGT_IGNORE: + continue; + } + + if ((n = res_nquery(pvt->res, p->qname, p->qclass, p->qtype, + p->answer, p->anslen)) < 0) { + querystate = RESQRY_FAIL; + continue; + } + + memset(&ai, 0, sizeof(ai)); + ai.ai_family = af; + hp = gethostans(this, p->answer, n, p->qname, T_PTR, af, size, + NULL, (const struct addrinfo *)&ai); + if (!hp) { + querystate = RESQRY_FAIL; + continue; + } + + memcpy(pvt->host_addr, addr, len); + pvt->h_addr_ptrs[0] = (char *)pvt->host_addr; + pvt->h_addr_ptrs[1] = NULL; + if (af == AF_INET && (pvt->res->options & RES_USE_INET6)) { + map_v4v6_address((char*)pvt->host_addr, + (char*)pvt->host_addr); + pvt->host.h_addrtype = AF_INET6; + pvt->host.h_length = IN6ADDRSZ; + } + + RES_SET_H_ERRNO(pvt->res, NETDB_SUCCESS); + return (hp); /* no more loop is necessary. */ + } + + return(NULL); /* H_ERRNO was set by subroutines */ } static struct hostent * ho_next(struct irs_ho *this) { + + UNUSED(this); + return (NULL); } static void ho_rewind(struct irs_ho *this) { + + UNUSED(this); + /* NOOP */ } @@ -367,6 +525,495 @@ ho_res_get(struct irs_ho *this) { return (pvt->res); } +/* XXX */ +extern struct addrinfo *addr2addrinfo __P((const struct addrinfo *, + const char *)); + +static struct addrinfo * +ho_addrinfo(struct irs_ho *this, const char *name, const struct addrinfo *pai) +{ + struct pvt *pvt = (struct pvt *)this->private; + int n; + char tmp[NS_MAXDNAME]; + const char *cp; + struct dns_res_target q, q2, q3, *p; + struct addrinfo sentinel, *cur; + int querystate = RESQRY_FAIL; + + if (init(this) == -1) + return (NULL); + + memset(&q, 0, sizeof(q2)); + memset(&q2, 0, sizeof(q2)); + memset(&q3, 0, sizeof(q3)); + memset(&sentinel, 0, sizeof(sentinel)); + cur = &sentinel; + + switch (pai->ai_family) { + case AF_UNSPEC: + /* prefer IPv6 */ + q.qclass = C_IN; + q.qtype = ns_t_a6; + q.answer = q.qbuf.buf; + q.anslen = sizeof(q.qbuf); + q.next = &q2; +#ifdef RES_USE_A6 + if ((pvt->res->options & RES_USE_A6) == 0) + q.action = RESTGT_IGNORE; + else +#endif + q.action = RESTGT_DOALWAYS; + q2.qclass = C_IN; + q2.qtype = T_AAAA; + q2.answer = q2.qbuf.buf; + q2.anslen = sizeof(q2.qbuf); + q2.next = &q3; + /* try AAAA only when A6 query fails */ + q2.action = RESTGT_AFTERFAILURE; + q3.qclass = C_IN; + q3.qtype = T_A; + q3.answer = q3.qbuf.buf; + q3.anslen = sizeof(q3.qbuf); + q3.action = RESTGT_DOALWAYS; + break; + case AF_INET: + q.qclass = C_IN; + q.qtype = T_A; + q.answer = q.qbuf.buf; + q.anslen = sizeof(q.qbuf); + q.action = RESTGT_DOALWAYS; + break; + case AF_INET6: + q.qclass = C_IN; + q.qtype = ns_t_a6; + q.answer = q.qbuf.buf; + q.anslen = sizeof(q.qbuf); + q.next = &q2; +#ifdef RES_USE_A6 + if ((pvt->res->options & RES_USE_A6) == 0) + q.action = RESTGT_IGNORE; + else +#endif + q.action = RESTGT_DOALWAYS; + q2.qclass = C_IN; + q2.qtype = T_AAAA; + q2.answer = q2.qbuf.buf; + q2.anslen = sizeof(q2.qbuf); + q2.action = RESTGT_AFTERFAILURE; + break; + default: + RES_SET_H_ERRNO(pvt->res, NO_RECOVERY); /* better error? */ + return(NULL); + } + + /* + * if there aren't any dots, it could be a user-level alias. + * this is also done in res_nquery() since we are not the only + * function that looks up host names. + */ + if (!strchr(name, '.') && (cp = res_hostalias(pvt->res, name, + tmp, sizeof tmp))) + name = cp; + + for (p = &q; p; p = p->next) { + struct addrinfo *ai; + + switch(p->action) { + case RESTGT_DOALWAYS: + break; + case RESTGT_AFTERFAILURE: + if (querystate == RESQRY_SUCCESS) + continue; + break; + case RESTGT_IGNORE: + continue; + } + + if ((n = res_nsearch(pvt->res, name, p->qclass, p->qtype, + p->answer, p->anslen)) < 0) { + querystate = RESQRY_FAIL; + continue; + } + (void)gethostans(this, p->answer, n, name, p->qtype, + pai->ai_family, /* XXX: meaningless */ + 0, &ai, pai); + if (ai) { + querystate = RESQRY_SUCCESS; + cur->ai_next = ai; + while (cur && cur->ai_next) + cur = cur->ai_next; + } + else + querystate = RESQRY_FAIL; + } + + return(sentinel.ai_next); +} + +static const u_char * +ar_head(cp, count, msg, eom, pvt, name_ok) + const u_char *cp, *msg, *eom; + int count; + struct pvt *pvt; + int (*name_ok)(const char *); +{ + int n; + char buf[1024]; /* XXX */ + + while (count-- > 0 && cp < eom) { + n = dn_expand(msg, eom, cp, buf, sizeof(buf)); + if (n < 0 || !maybe_ok(pvt->res, buf, name_ok)) + goto end; + cp += n; /* name */ + if (cp + 3 * INT16SZ + INT32SZ >= eom) + goto end; + cp += INT16SZ; /* type */ + cp += INT16SZ + INT32SZ; /* class, TTL */ + n = ns_get16(cp); + cp += n + INT16SZ; /* len */ + } + return(cp); + + end: + return(eom); /* XXX */ +} + +/* XXX: too many arguments */ +static struct addrinfo * +a6_expand(const u_char *ansbuf, const u_char *a6p, + int a6len, const u_char *arp, const u_char *eom, + const struct in6_addr *in6, int plen, const struct addrinfo *pai, + struct pvt *pvt, int (*name_ok)(const char *), int *errorp) +{ + struct in6_addr a; + int n, pbyte, plen1, pbyte1, error = 0; + const u_char *cp; + struct addrinfo sentinel, *cur; + char pname[1024], buf[1024]; /* XXX */ + + *errorp = NETDB_SUCCESS; + memset(&sentinel, 0, sizeof(sentinel)); + cur = &sentinel; + + /* + * Validate A6 parameters. + */ + if (a6len == 0) { /* an A6 record must contain at least 1 byte. */ + error = NO_RECOVERY; + goto bad; + } + /* prefix length check. */ + if ((plen1 = *a6p) > 128) { + error = NO_RECOVERY; + goto bad; + } + if (plen1 > plen) { + /* + * New length must not be greater than old one. + * Ignore the record as specified in RFC 2874 + * Section 3.1.2. + */ + return(NULL); /* just ignore. */ + } + /* boundary check for new plen and prefix addr */ + pbyte1 = (plen1 & ~7) / 8; + if ((int)sizeof(struct in6_addr) - pbyte1 > a6len - 1) { + error = NO_RECOVERY; + goto bad; + } + + /* + * merge the new prefix portion. + * <--- plen(bits) ---> + * <--- pbyte ---><-b-> + * 000000000000000pppppxxxxxxxxxxx(= in6, 0: unknown, x: known, p: pad) + * PP++++++++(+ should be merged. P: padding, must be 0) + * <-- plen1--> + * <-pbyte1-> + * ^a6p+1 + * The result should be: + * 0000000000PP++++++++xxxxxxxxxxx(= a) + */ + pbyte = (plen & ~7) / 8; + a = *in6; + if (pbyte > pbyte1) { + /* N.B. the case of "pbyte1 == 128" is implicitly excluded. */ + int b = plen % 8; /* = the length of "pp..." above */ + u_char c_hi, c_lo; + + memcpy(&a.s6_addr[pbyte1], a6p + 1, pbyte - pbyte1); + if (b > 0) { + c_hi = a6p[pbyte - pbyte1 + 1]; + c_lo = in6->s6_addr[pbyte]; + a.s6_addr[pbyte] = + (c_hi & (0xff << (8 - b))) | + ((0x00ff >> b) & c_lo); + } + } + +#if 0 /* for debug */ + if ((pvt->res->options & RES_DEBUG) != 0) { + u_char ntopbuf[INET6_ADDRSTRLEN]; + + inet_ntop(AF_INET6, &a, ntopbuf, sizeof(ntopbuf)); + printf("a6_expand: %s\\%d\n", ntopbuf, plen1); + } +#endif + + if (plen1 == 0) { + /* Here is the end of A6 chain. make addrinfo, then return. */ + return(addr2addrinfo(pai, (const char *)&a)); + } + + /* + * Expand the new prefix name. Since the prefix name must not be + * compressed (RFC 2874 Section 3.1.1), we could use ns_name_ntop() + * here if it had a stricter boundary check. + */ + cp = a6p + 1 + (sizeof(*in6) - pbyte1); + n = dn_expand(ansbuf, eom, cp, pname, sizeof(pname)); + if (n < 0 || !maybe_ok(pvt->res, pname, name_ok)) { + error = NO_RECOVERY; + goto bad; + } + if (cp + n != a6p + a6len) { /* length mismatch */ + error = NO_RECOVERY; + goto bad; + } + + /* + * we need (more) additional section records, but no one is + * available, which possibly means a malformed answer. + */ + if (arp == NULL) { + error = NO_RECOVERY; /* we can't resolve the chain. */ + goto bad; + } + + /* + * Loop thru the rest of the buffer, searching for the next A6 record + * that has the same owner name as the prefix name. If found, then + * recursively call this function to expand the whole A6 chain. + */ + plen = plen1; + for (cp = arp; cp != NULL && cp < eom; cp += n) { + int class, type; + + n = dn_expand(ansbuf, eom, cp, buf, sizeof(buf)); + if (n < 0 || !maybe_ok(pvt->res, buf, name_ok)) { + error = NO_RECOVERY; + goto bad; + } + cp += n; /* name */ + if (cp + 3 * INT16SZ + INT32SZ > eom) { + error = NO_RECOVERY; + goto bad; + } + type = ns_get16(cp); + cp += INT16SZ; /* type */ + class = ns_get16(cp); + cp += INT16SZ + INT32SZ; /* class, TTL */ + n = ns_get16(cp); + cp += INT16SZ; /* len */ + if (cp + n > eom) { + error = NO_RECOVERY; + goto bad; + } + if (class != C_IN || type != ns_t_a6) { + /* we are only interested in A6 records. skip others */ + continue; + } + + if (ns_samename(buf, pname) != 1) { + continue; + } + + /* Proceed to the next record in the chain. */ + cur->ai_next = a6_expand(ansbuf, cp, n, cp + n, eom, + (const struct in6_addr *)&a, + plen, pai, pvt, name_ok, &error); + if (error != NETDB_SUCCESS) + goto bad; + while (cur && cur->ai_next) + cur = cur->ai_next; + } + + return(sentinel.ai_next); + + bad: + *errorp = error; + if (sentinel.ai_next) + freeaddrinfo(sentinel.ai_next); + return(NULL); +} + +static const char * +dname_subst(const char *qname0, const char *owner0, const char *target) { + char owner[MAXDNAME]; + static char qname[MAXDNAME]; + const char blabelhead[] = "\\[x"; /* we can assume hex strings */ + int qlen, olen; + int bufsiz = sizeof(qname); + + /* make local copies, which are canonicalized. */ + if (ns_makecanon(qname0, qname, sizeof(qname)) < 0 || + ns_makecanon(owner0, owner, sizeof(owner)) < 0) + return(NULL); + qlen = strlen(qname); + olen = strlen(owner); + /* from now on, do not refer to qname0 nor owner0. */ + + /* + * check if QNAME is a subdomain of OWNER. + * XXX: currently, we only handle the following two cases: + * (A) none of the labels are bitlabels, or + * (B) both of the head labels are bitlabels (and the following + * labels are NOT bitlabels). + * If we pass the check, then subtract the remaining part from QNAME. + * ex. (A) qname=www.foo.com,owner=foo.com => new qname=www. + * (B) qname=\[x3ffe0501/32].foo.com,owner=\[x3ffe/16].foo.com + * => new qname=\[x0501/16]. + */ + if (ns_samedomain(qname, owner)) { /* check (A) */ + /* at this point, qlen must not be smaller than olen */ + qname[qlen - olen] = 0; + bufsiz -= (qlen - olen); + } else { /* check (B) */ + char *parent0, *parent1; + /* the following 3 have enough size to store 1 bitlabel */ + u_char qlabel[64], olabel[64], newlabel[64]; + int qlabellen, olabellen; + + if (strncmp(qname, blabelhead, 3) != 0 || + strncmp(owner, blabelhead, 3) != 0) + return(NULL); + /* + * Both two begin with bitlabels. The succeeding parts + * must exact match. + */ + if ((parent0 = strchr(qname, '.')) == NULL || + (parent1 = strchr(owner, '.')) == NULL) + return(NULL); + + /* ns_samename allows names to begin with '.' */ + if (ns_samename(parent0, parent1) != 1) + return(NULL); + + /* cut the upper domain parts off. */ + *(parent0 + 1) = 0; + *(parent1 + 1) = 0; + /* convert the textual form into binary one. */ + if (ns_name_pton(qname, qlabel, sizeof(qlabel)) < 0 || + ns_name_pton(owner, olabel, sizeof(olabel)) < 0) + return(NULL); + if ((qlabellen = *(qlabel + 1)) == 0) + qlabellen = 256; + if ((olabellen = *(olabel + 1)) == 0) + olabellen = 256; + if (olabellen > qlabellen) + return(NULL); /* owner does not contain qname. */ + else { + int qplen = (qlabellen + 7) / 8; + int oplen = (olabellen + 7) / 8; + int sft = olabellen % 8; + int nllen, n; + u_char *qp, *op, *np; + + /* skip ELT and Count. */ + qp = qlabel + 2; + op = olabel + 2; + + /* check if olabel is a "subdomain" of qlabel. */ + if (memcmp(qp, op, oplen - 1) != 0) + return(NULL); + if (sft > 0) { + /* compare trailing bits (between 1 and 7) */ + if ((qp[qplen - 1] & (0xff << sft)) != + op[qplen - 1]) + return(NULL); + } + + /* OK, get remaining bits from qlabel. */ + np = newlabel; + if (olabellen == qlabellen) { + /* + * Two names (including bitlabels) are exactly + * same. Discard the whole names. + * XXX: ns_samename() above should exclude + * this case... + */ + qname[0] = 0; + goto maketarget; + } + *np++ = 0x41; /* XXX hardcoding */ + *np++ = nllen = (qlabellen - olabellen); + if (sft == 0) { + /* + * No alignment issue. can just use memcpy. + * Note that the "else" part below contains + * this case. We separate the two cases just + * for efficiency. + * We assume that ns_name_pton above ensures + * QP does not contain trailing garbages. + */ + memcpy(np, qp + oplen, qplen - oplen); + np += qplen - oplen; + *np = 0; + } else { + /* + * copy the lower (8-SFT) bits of QP to the + * upper (8-SFT) bits of NP, then copy the + * upper SFT bits of QP+1 to the lower SFT bits + * of NP, and so on... + * if QP is xxxyyyyy zzzwww..., then + * NP would be yyyyyzzz ... + * Again, we assume QP does not contain + * trailing garbages. + */ + qp += (oplen - 1); + while (nllen > 0) { + *np = (*qp << sft) & 0xff; + if ((nllen -= (8 - sft)) <= 0) + break; /* done */ + qp++; + *np |= ((*qp >> sft) & 0xff); + np++; + nllen -= sft; + } + *++np = 0; + } + + /* + * make a new bitlabel with the remaining bits. + * Note that there's no buffer boundary issue, since + * qlabel, olabel, and newlabel all have the same size. + * ns_name_ntop() must not return 0, since we have + * a non-empty bitlabel. + */ + if ((n = ns_name_ntop(newlabel, qname, sizeof(qname))) + <= 0) + return(NULL); + bufsiz -= n; + if (qname[n - 1] != '.') { /* XXX no trailing dot */ + qname[n - 1] = '.'; + qname[n] = 0; + bufsiz--; + } + + } + } + + maketarget: + /* + * Finally, append the remaining part (maybe empty) to the new target. + */ + if (bufsiz < (int)strlen(target)) /* bufsiz takes care of the \0. */ + return(NULL); + strcat(qname, target); + + return((const char *)qname); +} + static void ho_res_set(struct irs_ho *this, struct __res_state *res, void (*free_res)(void *)) { @@ -386,23 +1033,37 @@ ho_res_set(struct irs_ho *this, struct __res_state *res, static struct hostent * gethostans(struct irs_ho *this, const u_char *ansbuf, int anslen, const char *qname, int qtype, - int af, int size) + int af, int size, /* meaningless for addrinfo cases */ + struct addrinfo **ret_aip, const struct addrinfo *pai) { struct pvt *pvt = (struct pvt *)this->private; int type, class, buflen, ancount, qdcount, n, haveanswer, had_error; + int error = NETDB_SUCCESS, arcount; int (*name_ok)(const char *); const HEADER *hp; const u_char *eom; + const u_char *eor; const u_char *cp; - const char *tname, **tap; + const char *tname; + const char *hname; char *bp, **ap, **hap; char tbuf[MAXDNAME+1]; + struct addrinfo sentinel, *cur, ai; + const u_char *arp = NULL; + + if (pai == NULL) abort(); + if (ret_aip != NULL) + *ret_aip = NULL; + memset(&sentinel, 0, sizeof(sentinel)); + cur = &sentinel; tname = qname; eom = ansbuf + anslen; switch (qtype) { + case ns_t_a6: case T_A: case T_AAAA: + case T_ANY: /* use T_ANY only for T_A/T_AAAA lookup */ name_ok = res_hnok; break; case T_PTR: @@ -414,7 +1075,7 @@ gethostans(struct irs_ho *this, pvt->host.h_addrtype = af; pvt->host.h_length = size; - pvt->host.h_name = NULL; + hname = pvt->host.h_name = NULL; /* * Find first satisfactory answer. @@ -423,9 +1084,10 @@ gethostans(struct irs_ho *this, RES_SET_H_ERRNO(pvt->res, NO_RECOVERY); return (NULL); } - hp = (HEADER *)ansbuf; + hp = (const HEADER *)ansbuf; ancount = ntohs(hp->ancount); qdcount = ntohs(hp->qdcount); + arcount = ntohs(hp->arcount); bp = pvt->hostbuf; buflen = sizeof pvt->hostbuf; cp = ansbuf + HFIXEDSZ; @@ -443,7 +1105,8 @@ gethostans(struct irs_ho *this, RES_SET_H_ERRNO(pvt->res, NO_RECOVERY); return (NULL); } - if (qtype == T_A || qtype == T_AAAA) { + if (qtype == T_A || qtype == T_AAAA || + qtype == ns_t_a6 || qtype == T_ANY) { /* res_nsend() has already verified that the query name is the * same as the one we sent; this just gets the expanded name * (i.e., with the succeeding search-domain tacked on). @@ -454,9 +1117,10 @@ gethostans(struct irs_ho *this, return (NULL); } pvt->host.h_name = bp; + hname = bp; bp += n; buflen -= n; - /* The qname can be abbreviated, but h_name is now absolute. */ + /* The qname can be abbreviated, but hname is now absolute. */ qname = pvt->host.h_name; } ap = pvt->host_aliases; @@ -486,10 +1150,12 @@ gethostans(struct irs_ho *this, cp += n; continue; } - if ((qtype == T_A || qtype == T_AAAA) && type == T_CNAME) { + eor = cp + n; + if ((qtype == T_A || qtype == T_AAAA || qtype == ns_t_a6 || + qtype == T_ANY) && type == T_CNAME) { if (ap >= &pvt->host_aliases[MAXALIASES-1]) continue; - n = dn_expand(ansbuf, eom, cp, tbuf, sizeof tbuf); + n = dn_expand(ansbuf, eor, cp, tbuf, sizeof tbuf); if (n < 0 || !maybe_ok(pvt->res, tbuf, name_ok)) { had_error++; continue; @@ -508,17 +1174,78 @@ gethostans(struct irs_ho *this, } strcpy(bp, tbuf); pvt->host.h_name = bp; + hname = bp; bp += n; buflen -= n; continue; } + if (type == ns_t_dname) { + const char *t0, *t; + + /* + * just replace the query target; do not update the + * alias list. (Or should we?) + */ + t0 = (qtype == T_PTR) ? tname : hname; + + n = dn_expand(ansbuf, eor, cp, tbuf, sizeof(tbuf)); + if (n < 0 || !maybe_dnok(pvt->res, tbuf)) { + had_error++; + continue; + } +#ifdef RES_USE_DNAME + if ((pvt ->res->options & RES_USE_DNAME) == 0) { + cp += n; + continue; + } +#endif + if ((t = dname_subst(t0, bp, tbuf)) == NULL) { + cp += n; + continue; + } +#if 0 /* for debug */ + if ((pvt->res->options & RES_DEBUG) != 0) { + printf("DNAME owner=%s, target=%s, next=%s\n", + bp, tbuf, t); + } +#endif + cp += n; + + n = strlen(t) + 1; /* for the \0 */ + if (n > buflen) { + had_error++; + continue; + } + strcpy(bp, t); + if (qtype == T_PTR) + tname = bp; + else + hname = bp; + bp += n; + buflen -= n; + + continue; + } if (qtype == T_PTR && type == T_CNAME) { - n = dn_expand(ansbuf, eom, cp, tbuf, sizeof tbuf); + n = dn_expand(ansbuf, eor, cp, tbuf, sizeof tbuf); if (n < 0 || !maybe_dnok(pvt->res, tbuf)) { had_error++; continue; } cp += n; +#ifdef RES_USE_DNAME + if ((pvt->res->options & RES_USE_DNAME) != 0) +#endif + { + /* + * We may be able to check this regardless + * of the USE_DNAME bit, but we add the check + * for now since the DNAME support is + * experimental. + */ + if (ns_samename(tname, bp) != 1) + continue; + } /* Get canonical name. */ n = strlen(tbuf) + 1; /* for the \0 */ if (n > buflen) { @@ -531,25 +1258,38 @@ gethostans(struct irs_ho *this, buflen -= n; continue; } - if (type != qtype) { + if (qtype == T_ANY) { + if (!(type == T_A || type == T_AAAA || + type == ns_t_a6)) { + cp += n; + continue; + } + } else if (type != qtype) { cp += n; continue; } switch (type) { case T_PTR: + if (ret_aip != NULL) { + /* addrinfo never needs T_PTR */ + cp += n; + continue; + } if (ns_samename(tname, bp) != 1) { cp += n; continue; } - n = dn_expand(ansbuf, eom, cp, bp, buflen); + n = dn_expand(ansbuf, eor, cp, bp, buflen); if (n < 0 || !maybe_hnok(pvt->res, bp) || n >= MAXHOSTNAMELEN) { had_error++; break; } cp += n; - if (!haveanswer) + if (!haveanswer) { pvt->host.h_name = bp; + hname = bp; + } else if (ap < &pvt->host_aliases[MAXALIASES-1]) *ap++ = bp; else @@ -560,16 +1300,91 @@ gethostans(struct irs_ho *this, buflen -= n; } break; + case ns_t_a6: { + struct in6_addr in6; + struct addrinfo ai; + +#ifdef RES_USE_A6 + if ((pvt->res->options & RES_USE_A6) == 0) { + cp += n; + continue; + } +#endif + + if (ns_samename(hname, bp) != 1) { + cp += n; + continue; + } + + /* + * search for the top of the additional section. + * once found, keep it for the case where we have + * more than one A6 record. + * XXX: however, we may not need this part. + */ + if (arp == NULL && arcount > 0) { + int nscount = ntohs(hp->nscount); + + arp = ar_head(cp + n, nscount + ancount - 1, + ansbuf, eom, pvt, name_ok); + } + + /* recursively collect the whole A6 chain */ + ai = *pai; /* XXX: we can't override constant pai */ + ai.ai_family = AF_INET6; + memset(&in6, 0, sizeof(in6)); /* just for safety */ + cur->ai_next = a6_expand(ansbuf, cp, n, arp, eom, + &in6, 128, + (const struct addrinfo *)&ai, + pvt, name_ok, &error); + if (error != NETDB_SUCCESS) { +#ifdef DEBUG + /* in this case, cur->ai_next must be NULL. */ + if (cur->ai_next != NULL) + abort(); +#endif + had_error++; + continue; + } + + /* + * We don't bother even if cur->ai_next is NULL unless + * the expansion failed by a fatal error. The list + * can be NULL if the given A6 is incomplete, but we + * may have another complete A6 chain in this answer. + * See the last paragraph of RFC 2874 Section 3.1.4. + */ + if (cur->ai_next == NULL) { + cp += n; + continue; /* no error, no answer */ + } + goto convertinfo; + } /* FALLTHROUGH */ case T_A: case T_AAAA: - if (ns_samename(pvt->host.h_name, bp) != 1) { + if (ns_samename(hname, bp) != 1) { + cp += n; + continue; + } + if (type == T_A && n != INADDRSZ) { cp += n; continue; } - if (n != pvt->host.h_length) { + if (type == T_AAAA && n != IN6ADDRSZ) { cp += n; continue; } + + /* make addrinfo. don't overwrite constant PAI */ + ai = *pai; + ai.ai_family = (type == T_AAAA) ? AF_INET6 : AF_INET; + cur->ai_next = addr2addrinfo( + (const struct addrinfo *)&ai, + (const char *)cp); + if (cur->ai_next == NULL) + had_error++; + + convertinfo: /* convert addrinfo into hostent form */ if (!haveanswer) { int nn; @@ -580,34 +1395,44 @@ gethostans(struct irs_ho *this, continue; } pvt->host.h_name = bp; + hname = bp; bp += nn; buflen -= nn; } /* Ensure alignment. */ - bp += sizeof(align) - ((u_long)bp % sizeof(align)); + bp = (char *)(((u_long)bp + (sizeof(align) - 1)) & + ~(sizeof(align) - 1)); /* Avoid overflows. */ if (bp + n >= &pvt->hostbuf[sizeof pvt->hostbuf]) { had_error++; continue; } - if (hap >= &pvt->h_addr_ptrs[MAXADDRS-1]) { - cp += n; - continue; - } - /* Suppress duplicates. */ - for (tap = (const char **)pvt->h_addr_ptrs; - *tap != NULL; - tap++) - if (memcmp(*tap, cp, n) == 0) - break; - if (*tap != NULL) { - cp += n; - continue; + if (ret_aip) { /* need addrinfo. keep it. */ + while (cur && cur->ai_next) + cur = cur->ai_next; + } else if (cur->ai_next) { /* need hostent */ + struct addrinfo *aip = cur->ai_next; + + for (aip = cur->ai_next; aip; + aip = aip->ai_next) { + int m; + + m = add_hostent(pvt, bp, hap, aip); + if (m < 0) { + had_error++; + break; + } + if (m == 0) + continue; + if (hap < &pvt->h_addr_ptrs[MAXADDRS-1]) + hap++; + + bp += m; + } + + freeaddrinfo(cur->ai_next); + cur->ai_next = NULL; } - /* Store address. */ - memcpy(*hap++ = bp, cp, n); - *hap = NULL; - bp += n; cp += n; break; default: @@ -617,27 +1442,94 @@ gethostans(struct irs_ho *this, haveanswer++; } if (haveanswer) { - *ap = NULL; - - if (pvt->res->nsort && haveanswer > 1 && qtype == T_A) - addrsort(pvt->res, pvt->h_addr_ptrs, haveanswer); - if (!pvt->host.h_name) { - n = strlen(qname) + 1; /* for the \0 */ - if (n > buflen || n >= MAXHOSTNAMELEN) - goto no_recovery; - strcpy(bp, qname); - pvt->host.h_name = bp; - bp += n; - buflen -= n; + if (ret_aip == NULL) { + *ap = NULL; + *hap = NULL; + + if (pvt->res->nsort && haveanswer > 1 && qtype == T_A) + addrsort(pvt->res, pvt->h_addr_ptrs, + haveanswer); + if (pvt->host.h_name == NULL) { + n = strlen(qname) + 1; /* for the \0 */ + if (n > buflen || n >= MAXHOSTNAMELEN) + goto no_recovery; + strcpy(bp, qname); + pvt->host.h_name = bp; + bp += n; + buflen -= n; + } + if (pvt->res->options & RES_USE_INET6) + map_v4v6_hostent(&pvt->host, &bp, &buflen); + RES_SET_H_ERRNO(pvt->res, NETDB_SUCCESS); + return (&pvt->host); + } else { + if ((pai->ai_flags & AI_CANONNAME) != 0) { + if (pvt->host.h_name == NULL) { + sentinel.ai_next->ai_canonname = + strdup(qname); + } + else { + sentinel.ai_next->ai_canonname = + strdup(pvt->host.h_name); + } + } + *ret_aip = sentinel.ai_next; + return(NULL); } - if (pvt->res->options & RES_USE_INET6) - map_v4v6_hostent(&pvt->host, &bp, &buflen); - RES_SET_H_ERRNO(pvt->res, NETDB_SUCCESS); - return (&pvt->host); } no_recovery: - RES_SET_H_ERRNO(pvt->res, NO_RECOVERY); - return (NULL); + if (sentinel.ai_next) { + /* this should be impossible, but check it for safety */ + freeaddrinfo(sentinel.ai_next); + } + if (error == NETDB_SUCCESS) + RES_SET_H_ERRNO(pvt->res, NO_RECOVERY); + else + RES_SET_H_ERRNO(pvt->res, error); + return(NULL); +} + +static int +add_hostent(struct pvt *pvt, char *bp, char **hap, struct addrinfo *ai) +{ + int addrlen; + char *addrp; + const char **tap; + char *obp = bp; + + switch(ai->ai_addr->sa_family) { + case AF_INET6: + addrlen = IN6ADDRSZ; + addrp = (char *)&((struct sockaddr_in6 *)ai->ai_addr)->sin6_addr; + break; + case AF_INET: + addrlen = INADDRSZ; + addrp = (char *)&((struct sockaddr_in *)ai->ai_addr)->sin_addr; + break; + default: + return(-1); /* abort? */ + } + + /* Ensure alignment. */ + bp = (char *)(((u_long)bp + (sizeof(align) - 1)) & + ~(sizeof(align) - 1)); + /* Avoid overflows. */ + if (bp + addrlen >= &pvt->hostbuf[sizeof pvt->hostbuf]) + return(-1); + if (hap >= &pvt->h_addr_ptrs[MAXADDRS-1]) + return(0); /* fail, but not treat it as an error. */ + + /* Suppress duplicates. */ + for (tap = (const char **)pvt->h_addr_ptrs; + *tap != NULL; + tap++) + if (memcmp(*tap, addrp, addrlen) == 0) + break; + if (*tap != NULL) + return (0); + + memcpy(*hap = bp, addrp, addrlen); + return((bp + addrlen) - obp); } static void @@ -649,7 +1541,10 @@ map_v4v6_hostent(struct hostent *hp, char **bpp, int *lenp) { hp->h_addrtype = AF_INET6; hp->h_length = IN6ADDRSZ; for (ap = hp->h_addr_list; *ap; ap++) { - int i = sizeof(align) - ((u_long)*bpp % sizeof(align)); + int i = (u_long)*bpp % sizeof(align); + + if (i != 0) + i = sizeof(align) - i; if (*lenp < (i + IN6ADDRSZ)) { /* Out of memory. Truncate address list here. */ diff --git a/contrib/bind/lib/irs/dns_nw.c b/contrib/bind/lib/irs/dns_nw.c index 66ef664..8e0e965 100644 --- a/contrib/bind/lib/irs/dns_nw.c +++ b/contrib/bind/lib/irs/dns_nw.c @@ -16,7 +16,7 @@ */ #if defined(LIBC_SCCS) && !defined(lint) -static const char rcsid[] = "$Id: dns_nw.c,v 1.19 1999/10/15 19:49:10 vixie Exp $"; +static const char rcsid[] = "$Id: dns_nw.c,v 1.21 2001/11/30 00:36:53 marka Exp $"; #endif /* LIBC_SCCS and not lint */ /* Imports. */ @@ -56,11 +56,7 @@ static const char rcsid[] = "$Id: dns_nw.c,v 1.19 1999/10/15 19:49:10 vixie Exp #define MAXALIASES 35 -#if PACKETSZ > 1024 -#define MAXPACKET PACKETSZ -#else -#define MAXPACKET 1024 -#endif +#define MAXPACKET (64*1024) struct pvt { struct nwent net; @@ -109,6 +105,8 @@ irs_dns_nw(struct irs_acc *this) { struct irs_nw *nw; struct pvt *pvt; + UNUSED(this); + if (!(pvt = memget(sizeof *pvt))) { errno = ENOMEM; return (NULL); @@ -185,11 +183,15 @@ nw_byaddr(struct irs_nw *this, void *net, int len, int af) { static struct nwent * nw_next(struct irs_nw *this) { + + UNUSED(this); + return (NULL); } static void nw_rewind(struct irs_nw *this) { + UNUSED(this); /* NOOP */ } @@ -539,7 +541,7 @@ normalize_name(char *name) { /* Make lower case. */ for (t = name; *t; t++) - if (isascii(*t) && isupper(*t)) + if (isascii((unsigned char)*t) && isupper((unsigned char)*t)) *t = tolower(*t); /* Remove trailing dots. */ diff --git a/contrib/bind/lib/irs/dns_pr.c b/contrib/bind/lib/irs/dns_pr.c index 77c6a93..64de35a 100644 --- a/contrib/bind/lib/irs/dns_pr.c +++ b/contrib/bind/lib/irs/dns_pr.c @@ -16,7 +16,7 @@ */ #if defined(LIBC_SCCS) && !defined(lint) -static const char rcsid[] = "$Id: dns_pr.c,v 1.14 1999/09/04 22:06:14 vixie Exp $"; +static const char rcsid[] = "$Id: dns_pr.c,v 1.15 2001/05/29 05:48:31 marka Exp $"; #endif /* Imports */ @@ -152,17 +152,20 @@ pr_bynumber(struct irs_pr *this, int num) { static struct protoent * pr_next(struct irs_pr *this) { + UNUSED(this); errno = ENODEV; return (NULL); } static void pr_rewind(struct irs_pr *this) { + UNUSED(this); /* NOOP */ } static void pr_minimize(struct irs_pr *this) { + UNUSED(this); /* NOOP */ } @@ -201,7 +204,7 @@ parse_hes_list(struct irs_pr *this, char **hes_list) { /* Skip blank lines. */ p = cp; - while (*p && !isspace(*p)) + while (*p && !isspace((unsigned char)*p)) p++; if (!*p) continue; @@ -213,14 +216,14 @@ parse_hes_list(struct irs_pr *this, char **hes_list) { p = pvt->prbuf; pvt->proto.p_name = p; - while (*p && !isspace(*p)) + while (*p && !isspace((unsigned char)*p)) p++; if (!*p) continue; *p++ = '\0'; pvt->proto.p_proto = atoi(p); - while (*p && !isspace(*p)) + while (*p && !isspace((unsigned char)*p)) p++; if (*p) *p++ = '\0'; @@ -237,7 +240,7 @@ parse_hes_list(struct irs_pr *this, char **hes_list) { pvt->proto.p_aliases = new; } pvt->proto.p_aliases[num++] = p; - while (*p && !isspace(*p)) + while (*p && !isspace((unsigned char)*p)) p++; if (*p) *p++ = '\0'; diff --git a/contrib/bind/lib/irs/dns_pw.c b/contrib/bind/lib/irs/dns_pw.c index 5344c6e..b3f7e05 100644 --- a/contrib/bind/lib/irs/dns_pw.c +++ b/contrib/bind/lib/irs/dns_pw.c @@ -16,7 +16,7 @@ */ #if defined(LIBC_SCCS) && !defined(lint) -static const char rcsid[] = "$Id: dns_pw.c,v 1.18 1999/09/04 22:06:14 vixie Exp $"; +static const char rcsid[] = "$Id: dns_pw.c,v 1.19 2001/05/29 05:48:32 marka Exp $"; #endif #include "port_before.h" @@ -133,17 +133,20 @@ pw_byuid(struct irs_pw *this, uid_t uid) { static struct passwd * pw_next(struct irs_pw *this) { + UNUSED(this); errno = ENODEV; return (NULL); } static void pw_rewind(struct irs_pw *this) { + UNUSED(this); /* NOOP */ } static void pw_minimize(struct irs_pw *this) { + UNUSED(this); /* NOOP */ } diff --git a/contrib/bind/lib/irs/dns_sv.c b/contrib/bind/lib/irs/dns_sv.c index e6cb2df..b3244a7 100644 --- a/contrib/bind/lib/irs/dns_sv.c +++ b/contrib/bind/lib/irs/dns_sv.c @@ -16,7 +16,7 @@ */ #if defined(LIBC_SCCS) && !defined(lint) -static const char rcsid[] = "$Id: dns_sv.c,v 1.19 2000/03/30 22:53:56 vixie Exp $"; +static const char rcsid[] = "$Id: dns_sv.c,v 1.20 2001/05/29 05:48:33 marka Exp $"; #endif /* Imports */ @@ -66,10 +66,12 @@ static struct servent * sv_byport(struct irs_sv *, int, const char *); static struct servent * sv_next(struct irs_sv *); static void sv_rewind(struct irs_sv *); static void sv_minimize(struct irs_sv *); +#ifdef SV_RES_SETGET static struct __res_state * sv_res_get(struct irs_sv *); static void sv_res_set(struct irs_sv *, struct __res_state *, void (*)(void *)); +#endif static struct servent * parse_hes_list(struct irs_sv *, char **, const char *); @@ -105,8 +107,13 @@ irs_dns_sv(struct irs_acc *this) { sv->rewind = sv_rewind; sv->close = sv_close; sv->minimize = sv_minimize; +#ifdef SV_RES_SETGET + sv->res_get = sv_res_get; + sv->res_set = sv_res_set; +#else sv->res_get = NULL; /* sv_res_get; */ sv->res_set = NULL; /* sv_res_set; */ +#endif return (sv); } @@ -161,12 +168,14 @@ sv_byport(struct irs_sv *this, int port, const char *proto) { static struct servent * sv_next(struct irs_sv *this) { + UNUSED(this); errno = ENODEV; return (NULL); } static void sv_rewind(struct irs_sv *this) { + UNUSED(this); /* NOOP */ } @@ -189,7 +198,7 @@ parse_hes_list(struct irs_sv *this, char **hes_list, const char *proto) { /* Check to make sure the protocol matches. */ p = cp; - while (*p && !isspace(*p)) + while (*p && !isspace((unsigned char)*p)) p++; if (!*p) continue; @@ -197,7 +206,7 @@ parse_hes_list(struct irs_sv *this, char **hes_list, const char *proto) { proto_len = strlen(proto); if (strncasecmp(++p, proto, proto_len) != 0) continue; - if (p[proto_len] && !isspace(p[proto_len])) + if (p[proto_len] && !isspace(p[proto_len]&0xff)) continue; } /* OK, we've got a live one. Let's parse it for real. */ @@ -207,21 +216,21 @@ parse_hes_list(struct irs_sv *this, char **hes_list, const char *proto) { p = pvt->svbuf; pvt->serv.s_name = p; - while (*p && !isspace(*p)) + while (*p && !isspace(*p&0xff)) p++; if (!*p) continue; *p++ = '\0'; pvt->serv.s_proto = p; - while (*p && !isspace(*p)) + while (*p && !isspace(*p&0xff)) p++; if (!*p) continue; *p++ = '\0'; pvt->serv.s_port = htons((u_short) atoi(p)); - while (*p && !isspace(*p)) + while (*p && !isspace(*p&0xff)) p++; if (*p) *p++ = '\0'; @@ -238,7 +247,7 @@ parse_hes_list(struct irs_sv *this, char **hes_list, const char *proto) { pvt->serv.s_aliases = new; } pvt->serv.s_aliases[num++] = p; - while (*p && !isspace(*p)) + while (*p && !isspace(*p&0xff)) p++; if (*p) *p++ = '\0'; @@ -265,9 +274,11 @@ parse_hes_list(struct irs_sv *this, char **hes_list, const char *proto) { static void sv_minimize(struct irs_sv *this) { + UNUSED(this); /* NOOP */ } +#ifdef SV_RES_SETGET static struct __res_state * sv_res_get(struct irs_sv *this) { struct pvt *pvt = (struct pvt *)this->private; @@ -284,3 +295,4 @@ sv_res_set(struct irs_sv *this, struct __res_state * res, __hesiod_res_set(dns->hes_ctx, res, free_res); } +#endif diff --git a/contrib/bind/lib/irs/gai_strerror.c b/contrib/bind/lib/irs/gai_strerror.c index f56c6f5..c487e68 100644 --- a/contrib/bind/lib/irs/gai_strerror.c +++ b/contrib/bind/lib/irs/gai_strerror.c @@ -1,45 +1,86 @@ /* -%%% copyright-cmetz-97 -This software is Copyright 1997-1998 by Craig Metz, All Rights Reserved. -The Inner Net License Version 2 applies to this software. -You should have received a copy of the license with this software. If -you didn't get a copy, you may request one from <license@inner.net>. - -*/ + * Copyright (c) 2001 by Internet Software Consortium. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS + * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE + * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS + * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + * SOFTWARE. + */ #include <port_before.h> #include <netdb.h> -#include <errno.h> #include <port_after.h> -char * -gai_strerror(int errnum) { - switch(errnum) { - case 0: - return "no error"; - case EAI_BADFLAGS: - return "invalid value for ai_flags"; - case EAI_NONAME: - return "name or service is not known"; - case EAI_AGAIN: - return "temporary failure in name resolution"; - case EAI_FAIL: - return "non-recoverable failure in name resolution"; - case EAI_NODATA: - return "no address associated with name"; - case EAI_FAMILY: - return "ai_family not supported"; - case EAI_SOCKTYPE: - return "ai_socktype not supported"; - case EAI_SERVICE: - return "service not supported for ai_socktype"; - case EAI_ADDRFAMILY: - return "address family for name not supported"; - case EAI_MEMORY: - return "memory allocation failure"; - case EAI_SYSTEM: - return "system error"; - default: - return "unknown error"; - }; +#ifdef DO_PTHREADS +#include <pthread.h> +#include <stdlib.h> +#endif + +static const char *gai_errlist[] = { + "no error", + "address family not supported for name",/* EAI_ADDRFAMILY */ + "temporary failure", /* EAI_AGAIN */ + "invalid flags", /* EAI_BADFLAGS */ + "permanent failure", /* EAI_FAIL */ + "address family not supported", /* EAI_FAMILY */ + "memory failure", /* EAI_MEMORY */ + "no address", /* EAI_NODATA */ + "unknown name or service", /* EAI_NONAME */ + "service not supported for socktype", /* EAI_SERVICE */ + "socktype not supported", /* EAI_SOCKTYPE */ + "system failure", /* EAI_SYSTEM */ + "bad hints", /* EAI_BADHINTS */ + "bad protocol", /* EAI_PROTOCOL */ + + "unknown error" /* Must be last. */ +}; + +static const int gai_nerr = (sizeof(gai_errlist)/sizeof(*gai_errlist)); + +#define EAI_BUFSIZE 128 + +const char * +gai_strerror(int ecode) { +#ifndef DO_PTHREADS + static char buf[EAI_BUFSIZE]; +#else /* DO_PTHREADS */ + static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER; + static pthread_key_t key; + static int once = 0; + char *buf; +#endif + + if (ecode >= 0 && ecode < (gai_nerr - 1)) + return (gai_errlist[ecode]); + +#ifdef DO_PTHREADS + if (!once) { + pthread_mutex_lock(&lock); + if (!once++) + pthread_key_create(&key, free); + pthread_mutex_unlock(&lock); + } + + buf = pthread_getspecific(key); + if (buf == NULL) { + buf = malloc(EAI_BUFSIZE); + if (buf == NULL) + return ("unknown error"); + pthread_setspecific(key, buf); + } +#endif + /* + * XXX This really should be snprintf(buf, EAI_BUFSIZE, ...). + * It is safe until message catalogs are used. + */ + sprintf(buf, "%s: %d", gai_errlist[gai_nerr - 1], ecode); + return (buf); } diff --git a/contrib/bind/lib/irs/gen.c b/contrib/bind/lib/irs/gen.c index fe41088..5ba7d52 100644 --- a/contrib/bind/lib/irs/gen.c +++ b/contrib/bind/lib/irs/gen.c @@ -16,7 +16,7 @@ */ #if !defined(LINT) && !defined(CODECENTER) -static const char rcsid[] = "$Id: gen.c,v 1.25 1999/10/13 16:39:29 vixie Exp $"; +static const char rcsid[] = "$Id: gen.c,v 1.26 2001/05/29 05:48:35 marka Exp $"; #endif /* @@ -399,7 +399,10 @@ init_map_rules(struct gen_p *irs, const char *conf_file) { char *tmp; int n; - for (tmp = line; isascii(*tmp) && isspace(*tmp); tmp++) + for (tmp = line; + isascii((unsigned char)*tmp) && + isspace((unsigned char)*tmp); + tmp++) (void)NULL; if (*tmp == '#' || *tmp == '\n' || *tmp == '\0') continue; diff --git a/contrib/bind/lib/irs/gen_gr.c b/contrib/bind/lib/irs/gen_gr.c index 14dfa2d..4b1b282 100644 --- a/contrib/bind/lib/irs/gen_gr.c +++ b/contrib/bind/lib/irs/gen_gr.c @@ -16,7 +16,7 @@ */ #if !defined(LINT) && !defined(CODECENTER) -static const char rcsid[] = "$Id: gen_gr.c,v 1.22 2000/07/11 05:51:56 vixie Exp $"; +static const char rcsid[] = "$Id: gen_gr.c,v 1.25 2001/06/07 02:12:26 marka Exp $"; #endif /* Imports */ @@ -324,8 +324,9 @@ gr_res_set(struct irs_gr *this, struct __res_state *res, static void grmerge(struct irs_gr *this, const struct group *src, int preserve) { struct pvt *pvt = (struct pvt *)this->private; - char *cp, **m, **p; - int n, ndst, nnew, memadj; + char *cp, **m, **p, *oldmembuf; + int n, ndst, nnew; + size_t used; if (!preserve) { pvt->group.gr_gid = src->gr_gid; @@ -372,15 +373,25 @@ grmerge(struct irs_gr *this, const struct group *src, int preserve) { /* No work to do. */ return; } - cp = realloc(pvt->membuf, pvt->membufsize + n); + used = preserve ? pvt->membufsize : 0; + cp = malloc(used + n); if (!cp) { /* No harm done, no work done. */ return; } - memadj = cp - pvt->membuf; + if (used != 0) + memcpy(cp, pvt->membuf, used); + oldmembuf = pvt->membuf; pvt->membuf = cp; - cp += pvt->membufsize; - pvt->membufsize += n; + pvt->membufsize = used + n; + cp += used; + + /* + * Adjust group.gr_mem. + */ + if (pvt->membuf != oldmembuf) + for (m = pvt->group.gr_mem; *m; m++) + *m = pvt->membuf + (*m - oldmembuf); /* * Add new elements. @@ -393,8 +404,10 @@ grmerge(struct irs_gr *this, const struct group *src, int preserve) { cp += strlen(cp) + 1; } if (preserve) { - pvt->group.gr_name += memadj; - pvt->group.gr_passwd += memadj; + pvt->group.gr_name = pvt->membuf + + (pvt->group.gr_name - oldmembuf); + pvt->group.gr_passwd = pvt->membuf + + (pvt->group.gr_passwd - oldmembuf); } else { pvt->group.gr_name = cp; strcpy(cp, src->gr_name); @@ -403,6 +416,8 @@ grmerge(struct irs_gr *this, const struct group *src, int preserve) { strcpy(cp, src->gr_passwd); cp += strlen(src->gr_passwd) + 1; } + if (oldmembuf != NULL) + free(oldmembuf); INSIST(cp >= pvt->membuf && cp <= &pvt->membuf[pvt->membufsize]); } diff --git a/contrib/bind/lib/irs/gen_ho.c b/contrib/bind/lib/irs/gen_ho.c index 9e7a429..12ed7cd 100644 --- a/contrib/bind/lib/irs/gen_ho.c +++ b/contrib/bind/lib/irs/gen_ho.c @@ -16,7 +16,7 @@ */ #if defined(LIBC_SCCS) && !defined(lint) -static const char rcsid[] = "$Id: gen_ho.c,v 1.15 1999/10/13 16:39:29 vixie Exp $"; +static const char rcsid[] = "$Id: gen_ho.c,v 1.16 2001/05/29 05:48:36 marka Exp $"; #endif /* LIBC_SCCS and not lint */ /* Imports */ @@ -68,6 +68,8 @@ static struct __res_state * ho_res_get(struct irs_ho *this); static void ho_res_set(struct irs_ho *this, struct __res_state *res, void (*free_res)(void *)); +static struct addrinfo * ho_addrinfo(struct irs_ho *this, const char *name, + const struct addrinfo *pai); static int init(struct irs_ho *this); @@ -102,6 +104,7 @@ irs_gen_ho(struct irs_acc *this) { ho->minimize = ho_minimize; ho->res_get = ho_res_get; ho->res_set = ho_res_set; + ho->addrinfo = ho_addrinfo; return (ho); } @@ -328,6 +331,51 @@ ho_res_set(struct irs_ho *this, struct __res_state *res, } } +static struct addrinfo * +ho_addrinfo(struct irs_ho *this, const char *name, const struct addrinfo *pai) +{ + struct pvt *pvt = (struct pvt *)this->private; + struct irs_rule *rule; + struct addrinfo *rval = NULL; + struct irs_ho *ho; + int therrno = NETDB_INTERNAL; + int softerror = 0; + + if (init(this) == -1) + return (NULL); + + for (rule = pvt->rules; rule; rule = rule->next) { + ho = rule->inst->ho; + RES_SET_H_ERRNO(pvt->res, NETDB_INTERNAL); + errno = 0; + if (ho->addrinfo == NULL) /* for safety */ + continue; + rval = (*ho->addrinfo)(ho, name, pai); + if (rval != NULL) + return (rval); + if (softerror == 0 && + pvt->res->res_h_errno != HOST_NOT_FOUND && + pvt->res->res_h_errno != NETDB_INTERNAL) { + softerror = 1; + therrno = pvt->res->res_h_errno; + } + if (rule->flags & IRS_CONTINUE) + continue; + /* + * See the comments in ho_byname() explaining + * the interpretation of TRY_AGAIN and ECONNREFUSED. + */ + if (pvt->res->res_h_errno != TRY_AGAIN || + errno != ECONNREFUSED) + break; + } + if (softerror != 0 && pvt->res->res_h_errno == HOST_NOT_FOUND) + RES_SET_H_ERRNO(pvt->res, therrno); + if (rval) + freeaddrinfo(rval); + return (NULL); +} + static int init(struct irs_ho *this) { struct pvt *pvt = (struct pvt *)this->private; diff --git a/contrib/bind/lib/irs/gen_ng.c b/contrib/bind/lib/irs/gen_ng.c index 064d616..c28b510 100644 --- a/contrib/bind/lib/irs/gen_ng.c +++ b/contrib/bind/lib/irs/gen_ng.c @@ -16,7 +16,7 @@ */ #if !defined(LINT) && !defined(CODECENTER) -static const char rcsid[] = "$Id: gen_ng.c,v 1.14 1999/10/13 16:39:29 vixie Exp $"; +static const char rcsid[] = "$Id: gen_ng.c,v 1.15 2001/05/29 05:48:38 marka Exp $"; #endif /* Imports */ @@ -52,7 +52,8 @@ struct pvt { /* Forward */ static void ng_close(struct irs_ng *); -static int ng_next(struct irs_ng *, char **, char **, char **); +static int ng_next(struct irs_ng *, const char **, + const char **, const char **); static int ng_test(struct irs_ng *, const char *, const char *, const char *, const char *); @@ -103,7 +104,9 @@ ng_close(struct irs_ng *this) { } static int -ng_next(struct irs_ng *this, char **host, char **user, char **domain) { +ng_next(struct irs_ng *this, const char **host, const char **user, + const char **domain) +{ struct pvt *pvt = (struct pvt *)this->private; struct irs_ng *ng; diff --git a/contrib/bind/lib/irs/gen_p.h b/contrib/bind/lib/irs/gen_p.h index b8210b0..35ef439 100644 --- a/contrib/bind/lib/irs/gen_p.h +++ b/contrib/bind/lib/irs/gen_p.h @@ -16,7 +16,7 @@ */ /* - * $Id: gen_p.h,v 1.10 1999/01/18 07:46:50 vixie Exp $ + * $Id: gen_p.h,v 1.11 2001/05/29 05:48:39 marka Exp $ */ /* Notes: @@ -90,7 +90,7 @@ struct irs_rule { * This is the private data for a search access class. */ struct gen_p { - const char * options; + char * options; struct irs_rule * map_rules[(int)irs_nmap]; struct irs_inst accessors[(int)irs_nacc]; struct __res_state * res; diff --git a/contrib/bind/lib/irs/getaddrinfo.c b/contrib/bind/lib/irs/getaddrinfo.c index f95a681..f2c533d 100644 --- a/contrib/bind/lib/irs/getaddrinfo.c +++ b/contrib/bind/lib/irs/getaddrinfo.c @@ -1,505 +1,1225 @@ -/*- - * Copyright (c) 1997 Berkeley Software Design, Inc. All rights reserved. - * The Berkeley Software Design Inc. software License Agreement specifies - * the terms and conditions for redistribution. +/* $KAME: getaddrinfo.c,v 1.14 2001/01/06 09:41:15 jinmei Exp $ */ + +/* + * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. * - * BSDI $Id: getaddrinfo.c,v 8.3 1999/06/11 01:25:58 vixie Exp $ + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. */ -#include <port_before.h> +/* + * Issues to be discussed: + * - Thread safe-ness must be checked. + * - Return values. There are nonstandard return values defined and used + * in the source code. This is because RFC2553 is silent about which error + * code must be returned for which situation. + * - IPv4 classful (shortened) form. RFC2553 is silent about it. XNET 5.2 + * says to use inet_aton() to convert IPv4 numeric to binary (allows + * classful form as a result). + * current code - disallow classful form for IPv4 (due to use of inet_pton). + * - freeaddrinfo(NULL). RFC2553 is silent about it. XNET 5.2 says it is + * invalid. + * current code - SEGV on freeaddrinfo(NULL) + * Note: + * - We use getipnodebyname() just for thread-safeness. There's no intent + * to let it do PF_UNSPEC (actually we never pass PF_UNSPEC to + * getipnodebyname(). + * - The code filters out AFs that are not supported by the kernel, + * when globbing NULL hostname (to loopback, or wildcard). Is it the right + * thing to do? What is the relationship with post-RFC2553 AI_ADDRCONFIG + * in ai_flags? + * - (post-2553) semantics of AI_ADDRCONFIG itself is too vague. + * (1) what should we do against numeric hostname (2) what should we do + * against NULL hostname (3) what is AI_ADDRCONFIG itself. AF not ready? + * non-loopback address configured? global address configured? + * - To avoid search order issue, we have a big amount of code duplicate + * from gethnamaddr.c and some other places. The issues that there's no + * lower layer function to lookup "IPv4 or IPv6" record. Calling + * gethostbyname2 from getaddrinfo will end up in wrong search order, as + * follows: + * - The code makes use of following calls when asked to resolver with + * ai_family = PF_UNSPEC: + * getipnodebyname(host, AF_INET6); + * getipnodebyname(host, AF_INET); + * This will result in the following queries if the node is configure to + * prefer /etc/hosts than DNS: + * lookup /etc/hosts for IPv6 address + * lookup DNS for IPv6 address + * lookup /etc/hosts for IPv4 address + * lookup DNS for IPv4 address + * which may not meet people's requirement. + * The right thing to happen is to have underlying layer which does + * PF_UNSPEC lookup (lookup both) and return chain of addrinfos. + * This would result in a bit of code duplicate with _dns_ghbyname() and + * friends. + */ + +#include "port_before.h" + +#include <sys/types.h> #include <sys/param.h> #include <sys/socket.h> -#include <sys/un.h> + +#include <net/if.h> #include <netinet/in.h> + +#include <arpa/inet.h> +#include <arpa/nameser.h> + #include <netdb.h> -#include <errno.h> +#include <resolv.h> #include <string.h> #include <stdlib.h> -#include <arpa/nameser.h> -#include <resolv.h> -#include <arpa/inet.h> -#include <port_after.h> - -#define SA(addr) ((struct sockaddr *)(addr)) -#define SIN(addr) ((struct sockaddr_in *)(addr)) -#define SIN6(addr) ((struct sockaddr_in6 *)(addr)) -#define SUN(addr) ((struct sockaddr_un *)(addr)) - -static struct addrinfo - *ai_reverse(struct addrinfo *oai), - *ai_clone(struct addrinfo *oai, int family), - *ai_alloc(int family, int addrlen); -#ifdef AF_LOCAL -static int get_local(const char *name, int socktype, struct addrinfo **res); +#include <stddef.h> +#include <ctype.h> +#include <unistd.h> +#include <stdio.h> +#include <errno.h> + +#include <stdarg.h> + +#include <irs.h> + +#include "port_after.h" + +#include "irs_data.h" + +/* + * if we enable it, we will see duplicated addrinfo entries on reply if both + * AAAA and A6 records are found. disable it for default installation. + */ +#undef T_A6 + +#define SUCCESS 0 +#define ANY 0 +#define YES 1 +#define NO 0 + +static const char in_addrany[] = { 0, 0, 0, 0 }; +static const char in6_addrany[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +}; +static const char in_loopback[] = { 127, 0, 0, 1 }; +static const char in6_loopback[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 +}; + +static const struct afd { + int a_af; + int a_addrlen; + int a_socklen; + int a_off; + const char *a_addrany; + const char *a_loopback; + int a_scoped; +} afdl [] = { + {PF_INET6, sizeof(struct in6_addr), + sizeof(struct sockaddr_in6), + offsetof(struct sockaddr_in6, sin6_addr), + in6_addrany, in6_loopback, 1}, + {PF_INET, sizeof(struct in_addr), + sizeof(struct sockaddr_in), + offsetof(struct sockaddr_in, sin_addr), + in_addrany, in_loopback, 0}, + {0, 0, 0, 0, NULL, NULL, 0}, +}; + +struct explore { + int e_af; + int e_socktype; + int e_protocol; + const char *e_protostr; + int e_wild; +#define WILD_AF(ex) ((ex)->e_wild & 0x01) +#define WILD_SOCKTYPE(ex) ((ex)->e_wild & 0x02) +#define WILD_PROTOCOL(ex) ((ex)->e_wild & 0x04) +}; + +static const struct explore explore[] = { +#if 0 + { PF_LOCAL, 0, ANY, ANY, NULL, 0x01 }, #endif + { PF_INET6, SOCK_DGRAM, IPPROTO_UDP, "udp", 0x07 }, + { PF_INET6, SOCK_STREAM, IPPROTO_TCP, "tcp", 0x07 }, + { PF_INET6, SOCK_RAW, ANY, NULL, 0x05 }, + { PF_INET, SOCK_DGRAM, IPPROTO_UDP, "udp", 0x07 }, + { PF_INET, SOCK_STREAM, IPPROTO_TCP, "tcp", 0x07 }, + { PF_INET, SOCK_RAW, ANY, NULL, 0x05 }, + { -1, 0, 0, NULL, 0 }, +}; + +#define PTON_MAX 16 + +#define MAXPACKET (1024*64) -static int add_ipv4(const char *hostname, int flags, struct addrinfo **aip, - int socktype, int port); -static int add_ipv6(const char *hostname, int flags, struct addrinfo **aip, - int socktype, int port); -static void set_order(int, int (**)()); +typedef union { + HEADER hdr; + u_char buf[MAXPACKET]; +} querybuf; + +static int str_isnumber __P((const char *)); +static int explore_fqdn __P((const struct addrinfo *, const char *, + const char *, struct addrinfo **)); +static int explore_copy __P((const struct addrinfo *, const struct addrinfo *, + struct addrinfo **)); +static int explore_null __P((const struct addrinfo *, + const char *, struct addrinfo **)); +static int explore_numeric __P((const struct addrinfo *, const char *, + const char *, struct addrinfo **)); +static int explore_numeric_scope __P((const struct addrinfo *, const char *, + const char *, struct addrinfo **)); +static int get_canonname __P((const struct addrinfo *, + struct addrinfo *, const char *)); +static struct addrinfo *get_ai __P((const struct addrinfo *, + const struct afd *, const char *)); +static struct addrinfo *copy_ai __P((const struct addrinfo *)); +static int get_portmatch __P((const struct addrinfo *, const char *)); +static int get_port __P((const struct addrinfo *, const char *, int)); +static const struct afd *find_afd __P((int)); +static int addrconfig __P((int)); +static int ip6_str2scopeid __P((char *, struct sockaddr_in6 *)); +static struct net_data *init __P((void)); + +struct addrinfo *hostent2addrinfo __P((struct hostent *, + const struct addrinfo *)); +struct addrinfo *addr2addrinfo __P((const struct addrinfo *, + const char *)); + +#if 0 +static const char *ai_errlist[] = { + "Success", + "Address family for hostname not supported", /* EAI_ADDRFAMILY */ + "Temporary failure in name resolution", /* EAI_AGAIN */ + "Invalid value for ai_flags", /* EAI_BADFLAGS */ + "Non-recoverable failure in name resolution", /* EAI_FAIL */ + "ai_family not supported", /* EAI_FAMILY */ + "Memory allocation failure", /* EAI_MEMORY */ + "No address associated with hostname", /* EAI_NODATA */ + "hostname nor servname provided, or not known", /* EAI_NONAME */ + "servname not supported for ai_socktype", /* EAI_SERVICE */ + "ai_socktype not supported", /* EAI_SOCKTYPE */ + "System error returned in errno", /* EAI_SYSTEM */ + "Invalid value for hints", /* EAI_BADHINTS */ + "Resolved protocol is unknown", /* EAI_PROTOCOL */ + "Unknown error", /* EAI_MAX */ +}; +#endif -#define FOUND_IPV4 0x1 -#define FOUND_IPV6 0x2 -#define FOUND_MAX 2 +/* XXX macros that make external reference is BAD. */ + +#define GET_AI(ai, afd, addr) \ +do { \ + /* external reference: pai, error, and label free */ \ + (ai) = get_ai(pai, (afd), (addr)); \ + if ((ai) == NULL) { \ + error = EAI_MEMORY; \ + goto free; \ + } \ +} while (/*CONSTCOND*/0) + +#define GET_PORT(ai, serv) \ +do { \ + /* external reference: error and label free */ \ + error = get_port((ai), (serv), 0); \ + if (error != 0) \ + goto free; \ +} while (/*CONSTCOND*/0) + +#define GET_CANONNAME(ai, str) \ +do { \ + /* external reference: pai, error and label free */ \ + error = get_canonname(pai, (ai), (str)); \ + if (error != 0) \ + goto free; \ +} while (/*CONSTCOND*/0) + +#define ERR(err) \ +do { \ + /* external reference: error, and label bad */ \ + error = (err); \ + goto bad; \ + /*NOTREACHED*/ \ +} while (/*CONSTCOND*/0) + +#define MATCH_FAMILY(x, y, w) \ + ((x) == (y) || (/*CONSTCOND*/(w) && ((x) == PF_UNSPEC || (y) == PF_UNSPEC))) +#define MATCH(x, y, w) \ + ((x) == (y) || (/*CONSTCOND*/(w) && ((x) == ANY || (y) == ANY))) + +#if 0 /* bind8 has its own version */ +char * +gai_strerror(ecode) + int ecode; +{ + if (ecode < 0 || ecode > EAI_MAX) + ecode = EAI_MAX; + return ai_errlist[ecode]; +} +#endif + +void +freeaddrinfo(ai) + struct addrinfo *ai; +{ + struct addrinfo *next; + + do { + next = ai->ai_next; + if (ai->ai_canonname) + free(ai->ai_canonname); + /* no need to free(ai->ai_addr) */ + free(ai); + ai = next; + } while (ai); +} + +static int +str_isnumber(p) + const char *p; +{ + char *ep; + + if (*p == '\0') + return NO; + ep = NULL; + (void)strtoul(p, &ep, 10); + if (ep && *ep == '\0') + return YES; + else + return NO; +} int -getaddrinfo(const char *hostname, const char *servname, - const struct addrinfo *hints, struct addrinfo **res) +getaddrinfo(hostname, servname, hints, res) + const char *hostname, *servname; + const struct addrinfo *hints; + struct addrinfo **res; { - struct servent *sp; - char *proto; - int family, socktype, flags, protocol; - struct addrinfo *ai, *ai_list; - int port, err, i; - int (*net_order[FOUND_MAX+1])(); + struct addrinfo sentinel; + struct addrinfo *cur; + int error = 0; + struct addrinfo ai, ai0, *afai; + struct addrinfo *pai; + const struct explore *ex; - if (hostname == NULL && servname == NULL) - return (EAI_NONAME); + memset(&sentinel, 0, sizeof(sentinel)); + cur = &sentinel; + pai = &ai; + pai->ai_flags = 0; + pai->ai_family = PF_UNSPEC; + pai->ai_socktype = ANY; + pai->ai_protocol = ANY; + pai->ai_addrlen = 0; + pai->ai_canonname = NULL; + pai->ai_addr = NULL; + pai->ai_next = NULL; - proto = NULL; - if (hints != NULL) { - if (hints->ai_flags & ~(AI_MASK)) - return (EAI_BADFLAGS); + if (hostname == NULL && servname == NULL) + return EAI_NONAME; + if (hints) { + /* error check for hints */ if (hints->ai_addrlen || hints->ai_canonname || - hints->ai_addr || hints->ai_next) { - errno = EINVAL; - return (EAI_SYSTEM); - } - family = hints->ai_family; - socktype = hints->ai_socktype; - protocol = hints->ai_protocol; - flags = hints->ai_flags; - switch (family) { - case AF_UNSPEC: - switch (hints->ai_socktype) { - case SOCK_STREAM: proto = "tcp"; break; - case SOCK_DGRAM: proto = "udp"; break; - } - break; - case AF_INET: - case AF_INET6: - switch (hints->ai_socktype) { - case 0: break; - case SOCK_STREAM: proto = "tcp"; break; - case SOCK_DGRAM: proto = "udp"; break; - case SOCK_RAW: break; - default: return (EAI_SOCKTYPE); - } - break; -#ifdef AF_LOCAL - case AF_LOCAL: - switch (hints->ai_socktype) { - case 0: break; - case SOCK_STREAM: break; - case SOCK_DGRAM: break; - default: return (EAI_SOCKTYPE); - } + hints->ai_addr || hints->ai_next) + ERR(EAI_BADHINTS); /* xxx */ + if (hints->ai_flags & ~AI_MASK) + ERR(EAI_BADFLAGS); + switch (hints->ai_family) { + case PF_UNSPEC: + case PF_INET: + case PF_INET6: break; -#endif default: - return (EAI_FAMILY); + ERR(EAI_FAMILY); + } + memcpy(pai, hints, sizeof(*pai)); + + /* + * if both socktype/protocol are specified, check if they + * are meaningful combination. + */ + if (pai->ai_socktype != ANY && pai->ai_protocol != ANY) { + for (ex = explore; ex->e_af >= 0; ex++) { + if (pai->ai_family != ex->e_af) + continue; + if (ex->e_socktype == ANY) + continue; + if (ex->e_protocol == ANY) + continue; + if (pai->ai_socktype == ex->e_socktype && + pai->ai_protocol != ex->e_protocol) { + ERR(EAI_BADHINTS); + } + } } - } else { - protocol = 0; - family = 0; - socktype = 0; - flags = 0; } -#ifdef AF_LOCAL /* - * First, deal with AF_LOCAL. If the family was not set, - * then assume AF_LOCAL if the first character of the - * hostname/servname is '/'. + * post-2553: AI_ALL and AI_V4MAPPED are effective only against + * AF_INET6 query. They needs to be ignored if specified in other + * occassions. */ + switch (pai->ai_flags & (AI_ALL | AI_V4MAPPED)) { + case AI_V4MAPPED: + case AI_ALL | AI_V4MAPPED: + if (pai->ai_family != AF_INET6) + pai->ai_flags &= ~(AI_ALL | AI_V4MAPPED); + break; + case AI_ALL: +#if 1 + /* illegal */ + ERR(EAI_BADFLAGS); +#else + pai->ai_flags &= ~(AI_ALL | AI_V4MAPPED); + break; +#endif + } - if (hostname && - (family == AF_LOCAL || (family == 0 && *hostname == '/'))) - return (get_local(hostname, socktype, res)); + /* + * check for special cases. (1) numeric servname is disallowed if + * socktype/protocol are left unspecified. (2) servname is disallowed + * for raw and other inet{,6} sockets. + */ + if (MATCH_FAMILY(pai->ai_family, PF_INET, 1) +#ifdef PF_INET6 + || MATCH_FAMILY(pai->ai_family, PF_INET6, 1) +#endif + ) { + ai0 = *pai; /* backup *pai */ - if (servname && - (family == AF_LOCAL || (family == 0 && *servname == '/'))) - return (get_local(servname, socktype, res)); + if (pai->ai_family == PF_UNSPEC) { +#ifdef PF_INET6 + pai->ai_family = PF_INET6; +#else + pai->ai_family = PF_INET; #endif + } + error = get_portmatch(pai, servname); + if (error) + ERR(error); + + *pai = ai0; + } + + ai0 = *pai; + + /* NULL hostname, or numeric hostname */ + for (ex = explore; ex->e_af >= 0; ex++) { + *pai = ai0; + + if (!MATCH_FAMILY(pai->ai_family, ex->e_af, WILD_AF(ex))) + continue; + if (!MATCH(pai->ai_socktype, ex->e_socktype, WILD_SOCKTYPE(ex))) + continue; + if (!MATCH(pai->ai_protocol, ex->e_protocol, WILD_PROTOCOL(ex))) + continue; + + if (pai->ai_family == PF_UNSPEC) + pai->ai_family = ex->e_af; + if (pai->ai_socktype == ANY && ex->e_socktype != ANY) + pai->ai_socktype = ex->e_socktype; + if (pai->ai_protocol == ANY && ex->e_protocol != ANY) + pai->ai_protocol = ex->e_protocol; + + /* + * if the servname does not match socktype/protocol, ignore it. + */ + if (get_portmatch(pai, servname) != 0) + continue; + + if (hostname == NULL) { + /* + * filter out AFs that are not supported by the kernel + * XXX errno? + */ + if (!addrconfig(pai->ai_family)) + continue; + error = explore_null(pai, servname, &cur->ai_next); + } else + error = explore_numeric_scope(pai, hostname, servname, + &cur->ai_next); + + if (error) + goto free; + + while (cur && cur->ai_next) + cur = cur->ai_next; + } /* - * Ok, only AF_INET and AF_INET6 left. + * XXX + * If numreic representation of AF1 can be interpreted as FQDN + * representation of AF2, we need to think again about the code below. */ - ai_list = NULL; + if (sentinel.ai_next) + goto good; + + if (pai->ai_flags & AI_NUMERICHOST) + ERR(EAI_NONAME); + if (hostname == NULL) + ERR(EAI_NONAME); /* - * First, look up the service name (port) if it was - * requested. If the socket type wasn't specified, then - * try and figure it out. + * hostname as alphabetical name. + * We'll make sure that + * - if returning addrinfo list is empty, return non-zero error + * value (already known one or EAI_NONAME). + * - otherwise, + * + if we haven't had any errors, return 0 (i.e. success). + * + if we've had an error, free the list and return the error. + * without any assumption on the behavior of explore_fqdn(). */ - if (servname) { - char *e; - - port = strtol(servname, &e, 10); - if (*e == '\0') { - if (socktype == 0) - return (EAI_SOCKTYPE); - if (port < 0 || port > 65535) - return (EAI_SERVICE); - port = htons(port); - } else { - sp = getservbyname(servname, proto); - if (sp == NULL) - return (EAI_SERVICE); - port = sp->s_port; - if (socktype == 0) { - if (strcmp(sp->s_proto, "tcp")) - socktype = SOCK_STREAM; - else if (strcmp(sp->s_proto, "udp")) - socktype = SOCK_DGRAM; - } - } - } else - port = 0; + + /* first, try to query DNS for all possible address families. */ + *pai = ai0; + error = explore_fqdn(pai, hostname, servname, &afai); + if (error) { + if (afai != NULL) + freeaddrinfo(afai); + goto free; + } + if (afai == NULL) { + error = EAI_NONAME; /* we've had no errors. */ + goto free; + } /* - * Next, deal with just a service name, and no hostname. - * (we verified that one of them was non-null up above). + * we would like to prefer AF_INET6 than AF_INET, so we'll make an + * outer loop by AFs. */ - if (hostname == NULL && (flags & AI_PASSIVE) != 0) { - if (family == AF_INET || family == 0) { - ai = ai_alloc(AF_INET, sizeof(struct sockaddr_in)); - if (ai == NULL) - return (EAI_MEMORY); - ai->ai_socktype = socktype; - ai->ai_protocol = protocol; - SIN(ai->ai_addr)->sin_port = port; - ai->ai_next = ai_list; - ai_list = ai; + for (ex = explore; ex->e_af >= 0; ex++) { + *pai = ai0; + + if (pai->ai_family == PF_UNSPEC) + pai->ai_family = ex->e_af; + + if (!MATCH_FAMILY(pai->ai_family, ex->e_af, WILD_AF(ex))) + continue; + if (!MATCH(pai->ai_socktype, ex->e_socktype, + WILD_SOCKTYPE(ex))) { + continue; + } + if (!MATCH(pai->ai_protocol, ex->e_protocol, + WILD_PROTOCOL(ex))) { + continue; } - if (family == AF_INET6 || family == 0) { - ai = ai_alloc(AF_INET6, sizeof(struct sockaddr_in6)); - if (ai == NULL) { - freeaddrinfo(ai_list); - return (EAI_MEMORY); - } - ai->ai_socktype = socktype; - ai->ai_protocol = protocol; - SIN6(ai->ai_addr)->sin6_port = port; - ai->ai_next = ai_list; - ai_list = ai; +#ifdef AI_ADDRCONFIG + /* + * If AI_ADDRCONFIG is specified, check if we are + * expected to return the address family or not. + */ + if ((pai->ai_flags & AI_ADDRCONFIG) != 0 && + !addrconfig(pai->ai_family)) + continue; +#endif + + if (pai->ai_family == PF_UNSPEC) + pai->ai_family = ex->e_af; + if (pai->ai_socktype == ANY && ex->e_socktype != ANY) + pai->ai_socktype = ex->e_socktype; + if (pai->ai_protocol == ANY && ex->e_protocol != ANY) + pai->ai_protocol = ex->e_protocol; + + /* + * if the servname does not match socktype/protocol, ignore it. + */ + if (get_portmatch(pai, servname) != 0) + continue; + + if ((error = explore_copy(pai, afai, &cur->ai_next)) != 0) { + freeaddrinfo(afai); + goto free; } - *res = ai_list; - return (0); + while (cur && cur->ai_next) + cur = cur->ai_next; } + freeaddrinfo(afai); /* afai must not be NULL at this point. */ + + /* we must not have got any errors. */ + if (error != 0) /* just for diagnosis */ + abort(); + + if (sentinel.ai_next) { +good: + *res = sentinel.ai_next; + return(SUCCESS); + } else { + /* + * All the process succeeded, but we've had an empty list. + * This can happen if the given hints do not match our + * candidates. + */ + error = EAI_NONAME; + } + +free: +bad: + if (sentinel.ai_next) + freeaddrinfo(sentinel.ai_next); + *res = NULL; + return(error); +} + +/* + * FQDN hostname, DNS lookup + */ +static int +explore_fqdn(pai, hostname, servname, res) + const struct addrinfo *pai; + const char *hostname; + const char *servname; + struct addrinfo **res; +{ + struct addrinfo *result; + struct addrinfo *cur; + struct net_data *net_data = init(); + struct irs_ho *ho; + int error = 0; + char tmp[NS_MAXDNAME]; + const char *cp; + + result = NULL; + /* - * If the family isn't specified or AI_NUMERICHOST specified, - * check first to see if it * is a numeric address. - * Though the gethostbyname2() routine - * will recognize numeric addresses, it will only recognize - * the format that it is being called for. Thus, a numeric - * AF_INET address will be treated by the AF_INET6 call as - * a domain name, and vice versa. Checking for both numerics - * here avoids that. + * if the servname does not match socktype/protocol, ignore it. */ - if (hostname != NULL && - (family == 0 || (flags & AI_NUMERICHOST) != 0)) { - char abuf[sizeof(struct in6_addr)]; - char nbuf[sizeof("xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx00")]; - int addrsize, addroff; - - if (inet_aton(hostname, (struct in_addr *)abuf)) { - if (family == AF_INET6) { - /* Convert to a V4 mapped address */ - struct in6_addr *a6 = (struct in6_addr *)abuf; - memcpy(&a6->s6_addr[12], &a6->s6_addr[0], 4); - memset(&a6->s6_addr[10], 0xff, 2); - memset(&a6->s6_addr[0], 0, 10); - goto inet6_addr; - } - addrsize = sizeof(struct in_addr); - addroff = (char *)(&SIN(0)->sin_addr) - (char *)0; - family = AF_INET; - goto common; - - } else if (inet_pton(AF_INET6, hostname, abuf)) { - if (family && family != AF_INET6) - return (EAI_NONAME); - inet6_addr: - addrsize = sizeof(struct in6_addr); - addroff = (char *)(&SIN6(0)->sin6_addr) - (char *)0; - family = AF_INET6; - - common: - if ((ai = ai_clone(ai_list, family)) == NULL) - return (EAI_MEMORY); - ai_list = ai; - ai->ai_socktype = socktype; - SIN(ai->ai_addr)->sin_port = port; - memcpy((char *)ai->ai_addr + addroff, abuf, addrsize); - if (flags & AI_CANONNAME) { - inet_ntop(family, abuf, nbuf, sizeof(nbuf)); - ai->ai_canonname = strdup(nbuf); - } - goto done; - } else if ((flags & AI_NUMERICHOST) != 0){ - return (EAI_NONAME); - } + if (get_portmatch(pai, servname) != 0) + return(0); + + if (!net_data || !(ho = net_data->ho)) + return(0); +#if 0 /* XXX (notyet) */ + if (net_data->ho_stayopen && net_data->ho_last && + net_data->ho_last->h_addrtype == af) { + if (ns_samename(name, net_data->ho_last->h_name) == 1) + return (net_data->ho_last); + for (hap = net_data->ho_last->h_aliases; hap && *hap; hap++) + if (ns_samename(name, *hap) == 1) + return (net_data->ho_last); } +#endif + if (!strchr(hostname, '.') && + (cp = res_hostalias(net_data->res, hostname, + tmp, sizeof(tmp)))) + hostname = cp; + result = (*ho->addrinfo)(ho, hostname, pai); + if (!net_data->ho_stayopen) { + (*ho->minimize)(ho); + } + if (result == NULL) { + int e = h_errno; - set_order(family, net_order); - for (i = 0; i < FOUND_MAX; i++) { - if (net_order[i] == NULL) + switch(e) { + case NETDB_INTERNAL: + error = EAI_SYSTEM; + break; + case TRY_AGAIN: + error = EAI_AGAIN; + break; + case NO_RECOVERY: + error = EAI_FAIL; + break; + case HOST_NOT_FOUND: + case NO_DATA: + error = EAI_NONAME; break; - if ((err = (net_order[i])(hostname, flags, &ai_list, - socktype, port)) != 0) - return(err); + default: + case NETDB_SUCCESS: /* should be impossible... */ + error = EAI_NONAME; + break; + } + goto free; } - if (ai_list == NULL) - return (EAI_NODATA); + for (cur = result; cur; cur = cur->ai_next) { + GET_PORT(cur, servname); /* XXX: redundant lookups... */ + /* canonname should already be filled. */ + } -done: - ai_list = ai_reverse(ai_list); + *res = result; - *res = ai_list; - return (0); + return(0); + +free: + if (result) + freeaddrinfo(result); + return error; } -static void -set_order(family, net_order) - int family; - int (**net_order)(); +static int +explore_copy(pai, src0, res) + const struct addrinfo *pai; /* seed */ + const struct addrinfo *src0; /* source */ + struct addrinfo **res; { - char *order, *tok; - int found; + int error; + struct addrinfo sentinel, *cur; + const struct addrinfo *src; - if (family) { - switch (family) { - case AF_INET: - *net_order++ = add_ipv4; - break; - case AF_INET6: - *net_order++ = add_ipv6; - break; - } - } else { - order = getenv("NET_ORDER"); - found = 0; - while (order != NULL) { - /* We ignore any unknown names. */ - tok = strsep(&order, ":"); - if (strcasecmp(tok, "inet6") == 0) { - if ((found & FOUND_IPV6) == 0) - *net_order++ = add_ipv6; - found |= FOUND_IPV6; - } else if (strcasecmp(tok, "inet") == 0 || - strcasecmp(tok, "inet4") == 0) { - if ((found & FOUND_IPV4) == 0) - *net_order++ = add_ipv4; - found |= FOUND_IPV4; - } + error = 0; + sentinel.ai_next = NULL; + cur = &sentinel; + + for (src = src0; src != NULL; src = src->ai_next) { + if (src->ai_family != pai->ai_family) + continue; + + cur->ai_next = copy_ai(src); + if (!cur->ai_next) { + error = EAI_MEMORY; + goto fail; } - /* Add in anything that we didn't find */ - if ((found & FOUND_IPV4) == 0) - *net_order++ = add_ipv4; - if ((found & FOUND_IPV6) == 0) - *net_order++ = add_ipv6; + cur->ai_next->ai_socktype = pai->ai_socktype; + cur->ai_next->ai_protocol = pai->ai_protocol; + cur = cur->ai_next; } - *net_order = NULL; - return; + + *res = sentinel.ai_next; + return 0; + +fail: + freeaddrinfo(sentinel.ai_next); + return error; } -static char v4_loop[4] = { 127, 0, 0, 1 }; +/* + * hostname == NULL. + * passive socket -> anyaddr (0.0.0.0 or ::) + * non-passive socket -> localhost (127.0.0.1 or ::1) + */ +static int +explore_null(pai, servname, res) + const struct addrinfo *pai; + const char *servname; + struct addrinfo **res; +{ + const struct afd *afd; + struct addrinfo *cur; + struct addrinfo sentinel; + int error; + + *res = NULL; + sentinel.ai_next = NULL; + cur = &sentinel; + + afd = find_afd(pai->ai_family); + if (afd == NULL) + return 0; + + if (pai->ai_flags & AI_PASSIVE) { + GET_AI(cur->ai_next, afd, afd->a_addrany); + /* xxx meaningless? + * GET_CANONNAME(cur->ai_next, "anyaddr"); + */ + GET_PORT(cur->ai_next, servname); + } else { + GET_AI(cur->ai_next, afd, afd->a_loopback); + /* xxx meaningless? + * GET_CANONNAME(cur->ai_next, "localhost"); + */ + GET_PORT(cur->ai_next, servname); + } + cur = cur->ai_next; + + *res = sentinel.ai_next; + return 0; + +free: + if (sentinel.ai_next) + freeaddrinfo(sentinel.ai_next); + return error; +} +/* + * numeric hostname + */ static int -add_ipv4(const char *hostname, int flags, struct addrinfo **aip, - int socktype, int port) +explore_numeric(pai, hostname, servname, res) + const struct addrinfo *pai; + const char *hostname; + const char *servname; + struct addrinfo **res; { - struct addrinfo *ai; - struct hostent *hp; - char **addr; + const struct afd *afd; + struct addrinfo *cur; + struct addrinfo sentinel; + int error; + char pton[PTON_MAX]; + + *res = NULL; + sentinel.ai_next = NULL; + cur = &sentinel; - if (hostname == NULL && (flags & AI_PASSIVE) == 0) { - if ((ai = ai_clone(*aip, AF_INET)) == NULL) { - freeaddrinfo(*aip); - return(EAI_MEMORY); + afd = find_afd(pai->ai_family); + if (afd == NULL) + return 0; + + switch (afd->a_af) { +#if 0 /*X/Open spec*/ + case AF_INET: + if (inet_aton(hostname, (struct in_addr *)pton) == 1) { + if (pai->ai_family == afd->a_af || + pai->ai_family == PF_UNSPEC /*?*/) { + GET_AI(cur->ai_next, afd, pton); + GET_PORT(cur->ai_next, servname); + while (cur && cur->ai_next) + cur = cur->ai_next; + } else + ERR(EAI_FAMILY); /*xxx*/ + } + break; +#endif + default: + if (inet_pton(afd->a_af, hostname, pton) == 1) { + if (pai->ai_family == afd->a_af || + pai->ai_family == PF_UNSPEC /*?*/) { + GET_AI(cur->ai_next, afd, pton); + GET_PORT(cur->ai_next, servname); + while (cur && cur->ai_next) + cur = cur->ai_next; + } else + ERR(EAI_FAMILY); /*xxx*/ } + break; + } - *aip = ai; - ai->ai_socktype = socktype; - SIN(ai->ai_addr)->sin_port = port; - memcpy(&SIN(ai->ai_addr)->sin_addr, v4_loop, 4); - } else if ((hp = gethostbyname2(hostname, AF_INET)) != NULL) { - for (addr = hp->h_addr_list; *addr; addr++) { - if ((ai = ai_clone(*aip, hp->h_addrtype)) == NULL) { - freeaddrinfo(*aip); - return(EAI_MEMORY); - } - *aip = ai; - ai->ai_socktype = socktype; - - /* We get IPv6 addresses if RES_USE_INET6 is set */ - if (hp->h_addrtype == AF_INET6) { - SIN6(ai->ai_addr)->sin6_port = port; - memcpy(&SIN6(ai->ai_addr)->sin6_addr, *addr, - hp->h_length); - } else { - SIN(ai->ai_addr)->sin_port = port; - memcpy(&SIN(ai->ai_addr)->sin_addr, *addr, - hp->h_length); + *res = sentinel.ai_next; + return 0; + +free: +bad: + if (sentinel.ai_next) + freeaddrinfo(sentinel.ai_next); + return error; +} + +/* + * numeric hostname with scope + */ +static int +explore_numeric_scope(pai, hostname, servname, res) + const struct addrinfo *pai; + const char *hostname; + const char *servname; + struct addrinfo **res; +{ +#ifndef SCOPE_DELIMITER + return explore_numeric(pai, hostname, servname, res); +#else + const struct afd *afd; + struct addrinfo *cur; + int error; + char *cp, *hostname2 = NULL, *scope, *addr; + struct sockaddr_in6 *sin6; + + afd = find_afd(pai->ai_family); + if (afd == NULL) + return 0; + + if (!afd->a_scoped) + return explore_numeric(pai, hostname, servname, res); + + cp = strchr(hostname, SCOPE_DELIMITER); + if (cp == NULL) + return explore_numeric(pai, hostname, servname, res); + + /* + * Handle special case of <scoped_address><delimiter><scope id> + */ + hostname2 = strdup(hostname); + if (hostname2 == NULL) + return EAI_MEMORY; + /* terminate at the delimiter */ + hostname2[cp - hostname] = '\0'; + addr = hostname2; + scope = cp + 1; + + error = explore_numeric(pai, addr, servname, res); + if (error == 0) { + int scopeid; + + for (cur = *res; cur; cur = cur->ai_next) { + if (cur->ai_family != AF_INET6) + continue; + sin6 = (struct sockaddr_in6 *)(void *)cur->ai_addr; + if ((scopeid = ip6_str2scopeid(scope, sin6)) == -1) { + free(hostname2); + return(EAI_NONAME); /* XXX: is return OK? */ } - if (flags & AI_CANONNAME) - ai->ai_canonname = strdup(hp->h_name); +#ifdef HAVE_SIN6_SCOPE_ID + sin6->sin6_scope_id = scopeid; +#endif } } - return(0); -} -static char v6_loop[16] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 }; + free(hostname2); + + return error; +#endif +} static int -add_ipv6(const char *hostname, int flags, struct addrinfo **aip, - int socktype, int port) +get_canonname(pai, ai, str) + const struct addrinfo *pai; + struct addrinfo *ai; + const char *str; { + if ((pai->ai_flags & AI_CANONNAME) != 0) { + ai->ai_canonname = (char *)malloc(strlen(str) + 1); + if (ai->ai_canonname == NULL) + return EAI_MEMORY; + strcpy(ai->ai_canonname, str); + } + return 0; +} + +static struct addrinfo * +get_ai(pai, afd, addr) + const struct addrinfo *pai; + const struct afd *afd; + const char *addr; +{ + char *p; struct addrinfo *ai; - struct hostent *hp; - char **addr; - if (hostname == NULL && (flags & AI_PASSIVE) == 0) { - if ((ai = ai_clone(*aip, AF_INET6)) == NULL) { - freeaddrinfo(*aip); - return(EAI_MEMORY); - } + ai = (struct addrinfo *)malloc(sizeof(struct addrinfo) + + (afd->a_socklen)); + if (ai == NULL) + return NULL; - *aip = ai; - ai->ai_socktype = socktype; - SIN6(ai->ai_addr)->sin6_port = port; - memcpy(&SIN6(ai->ai_addr)->sin6_addr, v6_loop, 16); - } else if ((hp = gethostbyname2(hostname, AF_INET6)) != NULL) { - for (addr = hp->h_addr_list; *addr; addr++) { - if ((ai = ai_clone(*aip, AF_INET6)) == NULL) { - freeaddrinfo(*aip); - return (EAI_MEMORY); - } - *aip = ai; - ai->ai_socktype = socktype; - SIN6(ai->ai_addr)->sin6_port = port; - memcpy(&SIN6(ai->ai_addr)->sin6_addr, *addr, - hp->h_length); - if (flags & AI_CANONNAME) - ai->ai_canonname = strdup(hp->h_name); + memcpy(ai, pai, sizeof(struct addrinfo)); + ai->ai_addr = (struct sockaddr *)(void *)(ai + 1); + memset(ai->ai_addr, 0, (size_t)afd->a_socklen); +#ifdef HAVE_SA_LEN + ai->ai_addr->sa_len = afd->a_socklen; +#endif + ai->ai_addrlen = afd->a_socklen; + ai->ai_addr->sa_family = ai->ai_family = afd->a_af; + p = (char *)(void *)(ai->ai_addr); + memcpy(p + afd->a_off, addr, (size_t)afd->a_addrlen); + return ai; +} + +/* XXX need to malloc() the same way we do from other functions! */ +static struct addrinfo * +copy_ai(pai) + const struct addrinfo *pai; +{ + struct addrinfo *ai; + size_t l; + + l = sizeof(*ai) + pai->ai_addrlen; + if ((ai = (struct addrinfo *)malloc(l)) == NULL) + return NULL; + memset(ai, 0, l); + memcpy(ai, pai, sizeof(*ai)); + ai->ai_addr = (struct sockaddr *)(void *)(ai + 1); + memcpy(ai->ai_addr, pai->ai_addr, pai->ai_addrlen); + + if (pai->ai_canonname) { + l = strlen(pai->ai_canonname) + 1; + if ((ai->ai_canonname = malloc(l)) == NULL) { + free(ai); + return NULL; } +#ifdef HAVE_STRLCPY + strlcpy(ai->ai_canonname, pai->ai_canonname, l); +#else + strncpy(ai->ai_canonname, pai->ai_canonname, l); +#endif + } else { + /* just to make sure */ + ai->ai_canonname = NULL; } - return (0); + + ai->ai_next = NULL; + + return ai; } -void -freeaddrinfo(struct addrinfo *ai) { - struct addrinfo *ai_next; +static int +get_portmatch(const struct addrinfo *ai, const char *servname) { - while (ai != NULL) { - ai_next = ai->ai_next; - if (ai->ai_addr) - free(ai->ai_addr); - if (ai->ai_canonname) - free(ai->ai_canonname); - free(ai); - ai = ai_next; - } + /* get_port does not touch first argument. when matchonly == 1. */ + /* LINTED const cast */ + return get_port((const struct addrinfo *)ai, servname, 1); } -#ifdef AF_LOCAL static int -get_local(const char *name, int socktype, struct addrinfo **res) { - struct addrinfo *ai; - struct sockaddr_un *sun; +get_port(const struct addrinfo *ai, const char *servname, int matchonly) { + const char *proto; + struct servent *sp; + int port; + int allownumeric; - if (socktype == 0) - return (EAI_SOCKTYPE); + if (servname == NULL) + return 0; + switch (ai->ai_family) { + case AF_INET: +#ifdef AF_INET6 + case AF_INET6: +#endif + break; + default: + return 0; + } - if ((ai = ai_alloc(AF_LOCAL, sizeof(*sun))) == NULL) - return (EAI_MEMORY); + switch (ai->ai_socktype) { + case SOCK_RAW: + return EAI_SERVICE; + case SOCK_DGRAM: + case SOCK_STREAM: + allownumeric = 1; + break; + case ANY: + allownumeric = 0; + break; + default: + return EAI_SOCKTYPE; + } - sun = SUN(ai->ai_addr); - strncpy(sun->sun_path, name, sizeof(sun->sun_path)); + if (str_isnumber(servname)) { + if (!allownumeric) + return EAI_SERVICE; + port = htons(atoi(servname)); + if (port < 0 || port > 65535) + return EAI_SERVICE; + } else { + switch (ai->ai_socktype) { + case SOCK_DGRAM: + proto = "udp"; + break; + case SOCK_STREAM: + proto = "tcp"; + break; + default: + proto = NULL; + break; + } - ai->ai_socktype = socktype; - /* - * ai->ai_flags, ai->ai_protocol, ai->ai_canonname, - * and ai->ai_next were initialized to zero. - */ + if ((sp = getservbyname(servname, proto)) == NULL) + return EAI_SERVICE; + port = sp->s_port; + } + + if (!matchonly) { + switch (ai->ai_family) { + case AF_INET: + ((struct sockaddr_in *)(void *) + ai->ai_addr)->sin_port = port; + break; + case AF_INET6: + ((struct sockaddr_in6 *)(void *) + ai->ai_addr)->sin6_port = port; + break; + } + } - *res = ai; - return (0); + return 0; +} + +static const struct afd * +find_afd(af) + int af; +{ + const struct afd *afd; + + if (af == PF_UNSPEC) + return NULL; + for (afd = afdl; afd->a_af; afd++) { + if (afd->a_af == af) + return afd; + } + return NULL; } -#endif /* - * Allocate an addrinfo structure, and a sockaddr structure - * of the specificed length. We initialize: - * ai_addrlen - * ai_family - * ai_addr - * ai_addr->sa_family - * ai_addr->sa_len (HAVE_SA_LEN) - * and everything else is initialized to zero. + * post-2553: AI_ADDRCONFIG check. if we use getipnodeby* as backend, backend + * will take care of it. + * the semantics of AI_ADDRCONFIG is not defined well. we are not sure + * if the code is right or not. */ -static struct addrinfo * -ai_alloc(int family, int addrlen) { - struct addrinfo *ai; +static int +addrconfig(af) + int af; +{ + int s; - if ((ai = (struct addrinfo *)calloc(1, sizeof(*ai))) == NULL) - return (NULL); + /* XXX errno */ + s = socket(af, SOCK_DGRAM, 0); + if (s < 0) { + if (errno != EMFILE) + return 0; + } else + close(s); + return 1; +} - if ((ai->ai_addr = SA(calloc(1, addrlen))) == NULL) { - free(ai); - return (NULL); +/* convert a string to a scope identifier. XXX: IPv6 specific */ +static int +ip6_str2scopeid(scope, sin6) + char *scope; + struct sockaddr_in6 *sin6; +{ + int scopeid; + struct in6_addr *a6 = &sin6->sin6_addr; + char *ep; + + /* empty scopeid portion is invalid */ + if (*scope == '\0') + return -1; + +#ifdef USE_IFNAMELINKID + if (IN6_IS_ADDR_LINKLOCAL(a6) || IN6_IS_ADDR_MC_LINKLOCAL(a6)) { + /* + * Using interface names as link indices can be allowed + * only when we can assume a one-to-one mappings between + * links and interfaces. See comments in getnameinfo.c. + */ + scopeid = if_nametoindex(scope); + if (scopeid == 0) + goto trynumeric; + return(scopeid); } - ai->ai_addrlen = addrlen; - ai->ai_family = family; - ai->ai_addr->sa_family = family; -#ifdef HAVE_SA_LEN - ai->ai_addr->sa_len = addrlen; #endif - return (ai); + + /* still unclear about literal, allow numeric only - placeholder */ + if (IN6_IS_ADDR_SITELOCAL(a6) || IN6_IS_ADDR_MC_SITELOCAL(a6)) + goto trynumeric; + if (IN6_IS_ADDR_MC_ORGLOCAL(a6)) + goto trynumeric; + else + goto trynumeric; /* global */ + + /* try to convert to a numeric id as a last resort */ +trynumeric: + scopeid = (int)strtoul(scope, &ep, 10); + if (*ep == '\0') + return scopeid; + else + return -1; } -static struct addrinfo * -ai_clone(struct addrinfo *oai, int family) { - struct addrinfo *ai; +struct addrinfo * +hostent2addrinfo(hp, pai) + struct hostent *hp; + const struct addrinfo *pai; +{ + int i, af, error = 0; + char **aplist = NULL, *ap; + struct addrinfo sentinel, *cur; + const struct afd *afd; + + af = hp->h_addrtype; + if (pai->ai_family != AF_UNSPEC && af != pai->ai_family) + return(NULL); + + afd = find_afd(af); + if (afd == NULL) + return(NULL); + + aplist = hp->h_addr_list; - ai = ai_alloc(family, ((family == AF_INET6) ? - sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in))); + memset(&sentinel, 0, sizeof(sentinel)); + cur = &sentinel; - if (ai == NULL) { - freeaddrinfo(oai); - return (NULL); + for (i = 0; (ap = aplist[i]) != NULL; i++) { +#if 0 /* the trick seems too much */ + af = hp->h_addr_list; + if (af == AF_INET6 && + IN6_IS_ADDR_V4MAPPED((struct in6_addr *)ap)) { + af = AF_INET; + ap = ap + sizeof(struct in6_addr) + - sizeof(struct in_addr); + } + afd = find_afd(af); + if (afd == NULL) + continue; +#endif /* 0 */ + + GET_AI(cur->ai_next, afd, ap); + + /* GET_PORT(cur->ai_next, servname); */ + if ((pai->ai_flags & AI_CANONNAME) != 0) { + /* + * RFC2553 says that ai_canonname will be set only for + * the first element. we do it for all the elements, + * just for convenience. + */ + GET_CANONNAME(cur->ai_next, hp->h_name); + } + while (cur && cur->ai_next) /* no need to loop, actually. */ + cur = cur->ai_next; + continue; + + free: + if (cur->ai_next) + freeaddrinfo(cur->ai_next); + cur->ai_next = NULL; + /* continue, without tht pointer CUR advanced. */ } - if (oai == NULL) - return (ai); - - ai->ai_flags = oai->ai_flags; - ai->ai_socktype = oai->ai_socktype; - ai->ai_protocol = oai->ai_protocol; - ai->ai_canonname = NULL; - ai->ai_next = oai; - return (ai); + + return(sentinel.ai_next); } -static struct addrinfo * -ai_reverse(struct addrinfo *oai) { - struct addrinfo *nai, *tai; - - nai = NULL; - - while (oai) { - /* grab one off the old list */ - tai = oai; - oai = oai->ai_next; - /* put it on the front of the new list */ - tai->ai_next = nai; - nai = tai; +struct addrinfo * +addr2addrinfo(pai, cp) + const struct addrinfo *pai; + const char *cp; +{ + const struct afd *afd; + + afd = find_afd(pai->ai_family); + if (afd == NULL) + return(NULL); + + return(get_ai(pai, afd, cp)); +} + +static struct net_data * +init() +{ + struct net_data *net_data; + + if (!(net_data = net_data_init(NULL))) + goto error; + if (!net_data->ho) { + net_data->ho = (*net_data->irs->ho_map)(net_data->irs); + if (!net_data->ho || !net_data->res) { +error: + errno = EIO; + if (net_data && net_data->res) + RES_SET_H_ERRNO(net_data->res, NETDB_INTERNAL); + return (NULL); + } + + (*net_data->ho->res_set)(net_data->ho, net_data->res, NULL); } - return (nai); + + return (net_data); } diff --git a/contrib/bind/lib/irs/getgrent.c b/contrib/bind/lib/irs/getgrent.c index 866e8c5..f6eea13 100644 --- a/contrib/bind/lib/irs/getgrent.c +++ b/contrib/bind/lib/irs/getgrent.c @@ -16,7 +16,7 @@ */ #if !defined(LINT) && !defined(CODECENTER) -static const char rcsid[] = "$Id: getgrent.c,v 1.19 1999/10/13 16:39:30 vixie Exp $"; +static const char rcsid[] = "$Id: getgrent.c,v 1.20 2001/05/29 05:48:41 marka Exp $"; #endif /* Imports */ @@ -36,6 +36,8 @@ static int __bind_irs_gr_unneeded; #include <grp.h> #include <resolv.h> #include <stdio.h> +#include <string.h> +#include <unistd.h> #include <irs.h> @@ -80,14 +82,14 @@ setgroupent(int stayopen) { #ifdef SETGRENT_VOID void -setgrent() { +setgrent(void) { struct net_data *net_data = init(); - return (setgrent_p(net_data)); + setgrent_p(net_data); } #else int -setgrent() { +setgrent(void) { struct net_data *net_data = init(); return (setgrent_p(net_data)); @@ -102,7 +104,7 @@ endgrent() { } int -getgrouplist(const char *name, gid_t basegid, gid_t *groups, int *ngroups) { +getgrouplist(GETGROUPLIST_ARGS) { struct net_data *net_data = init(); return (getgrouplist_p(name, basegid, groups, ngroups, net_data)); @@ -142,7 +144,7 @@ getgrgid_p(gid_t gid, struct net_data *net_data) { if (!net_data || !(gr = net_data->gr)) return (NULL); if (net_data->gr_stayopen && net_data->gr_last && - net_data->gr_last->gr_gid == gid) + (gid_t)net_data->gr_last->gr_gid == gid) return (net_data->gr_last); net_data->gr_last = (*gr->bygid)(gr, gid); if (!net_data->gr_stayopen) diff --git a/contrib/bind/lib/irs/getgrent_r.c b/contrib/bind/lib/irs/getgrent_r.c index df055db..641a2b2 100644 --- a/contrib/bind/lib/irs/getgrent_r.c +++ b/contrib/bind/lib/irs/getgrent_r.c @@ -16,7 +16,7 @@ */ #if defined(LIBC_SCCS) && !defined(lint) -static const char rcsid[] = "$Id: getgrent_r.c,v 8.4 1999/01/18 07:46:51 vixie Exp $"; +static const char rcsid[] = "$Id: getgrent_r.c,v 8.7 2001/11/01 08:02:08 marka Exp $"; #endif /* LIBC_SCCS and not lint */ #include <port_before.h> @@ -26,7 +26,17 @@ static const char rcsid[] = "$Id: getgrent_r.c,v 8.4 1999/01/18 07:46:51 vixie E #include <errno.h> #include <string.h> #include <stdio.h> +#include <sys/types.h> +#if (defined(POSIX_GETGRNAM_R) || defined(POSIX_GETGRGID_R)) && \ + defined(_POSIX_PTHREAD_SEMANTICS) + /* turn off solaris remapping in <grp.h> */ +#define _UNIX95 +#undef _POSIX_PTHREAD_SEMANTICS #include <grp.h> +#define _POSIX_PTHREAD_SEMANTICS 1 +#else +#include <grp.h> +#endif #include <sys/param.h> #include <port_after.h> @@ -50,7 +60,7 @@ getgrnam_r(const char *name, struct group *gptr, if (ge == NULL) { *result = NULL; - return (-1); + return (0); } res = copy_group(ge, gptr, buf, buflen); @@ -75,11 +85,11 @@ getgrnam_r(const char *name, struct group *gptr, /* POSIX 1003.1c */ #ifdef POSIX_GETGRGID_R int -__posix_getgrgid_r(const gid_t gid, struct group *gptr, +__posix_getgrgid_r(gid_t gid, struct group *gptr, char *buf, int buflen, struct group **result) { #else /* POSIX_GETGRGID_R */ int -getgrgid_r(const gid_t gid, struct group *gptr, +getgrgid_r(gid_t gid, struct group *gptr, char *buf, size_t buflen, struct group **result) { #endif /* POSIX_GETGRGID_R */ struct group *ge = getgrgid(gid); @@ -87,7 +97,7 @@ getgrgid_r(const gid_t gid, struct group *gptr, if (ge == NULL) { *result = NULL; - return (-1); + return (0); } res = copy_group(ge, gptr, buf, buflen); @@ -97,7 +107,7 @@ getgrgid_r(const gid_t gid, struct group *gptr, #ifdef POSIX_GETGRGID_R struct group * -getgrgid_r(const gid_t gid, struct group *gptr, +getgrgid_r(gid_t gid, struct group *gptr, char *buf, int buflen) { struct group *ge = getgrgid(gid); int res; @@ -181,7 +191,7 @@ copy_group(struct group *ge, struct group *gptr, char *buf, int buflen) { if (len > buflen) { errno = ERANGE; - return (-1); + return (ERANGE); } /* copy group id */ diff --git a/contrib/bind/lib/irs/gethostent.c b/contrib/bind/lib/irs/gethostent.c index 5aa46c5..586fa49 100644 --- a/contrib/bind/lib/irs/gethostent.c +++ b/contrib/bind/lib/irs/gethostent.c @@ -16,7 +16,7 @@ */ #if !defined(LINT) && !defined(CODECENTER) -static const char rcsid[] = "$Id: gethostent.c,v 1.28 2001/03/01 05:47:44 marka Exp $"; +static const char rcsid[] = "$Id: gethostent.c,v 1.29 2001/05/29 05:48:44 marka Exp $"; #endif /* Imports */ @@ -215,10 +215,6 @@ endhostent_p(struct net_data *net_data) { (*ho->minimize)(ho); } -#if !defined(HAS_INET6_STRUCTS) || defined(MISSING_IN6ADDR_ANY) -static const struct in6_addr in6addr_any; -#endif - #ifndef IN6_IS_ADDR_V4COMPAT static const unsigned char in6addr_compat[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; @@ -299,7 +295,7 @@ getipnodebyname(const char *name, int af, int flags, int *error_num) { char *addr_list[2]; char *aliases[1]; - he.h_name = (char *)name; + DE_CONST(name, he.h_name); he.h_addr_list = addr_list; he.h_addr_list[0] = (v4 == 1) ? (char *)&in4 : (char *)&in6; he.h_addr_list[1] = NULL; @@ -379,8 +375,10 @@ getipnodebyaddr(const void *src, size_t len, int af, int *error_num) { /* * Lookup IPv4 and IPv4 mapped/compatible addresses */ - if ((af == AF_INET6 && IN6_IS_ADDR_V4COMPAT((struct in6_addr *)src)) || - (af == AF_INET6 && IN6_IS_ADDR_V4MAPPED((struct in6_addr *)src)) || + if ((af == AF_INET6 && + IN6_IS_ADDR_V4COMPAT((const struct in6_addr *)src)) || + (af == AF_INET6 && + IN6_IS_ADDR_V4MAPPED((const struct in6_addr *)src)) || (af == AF_INET)) { const char *cp = src; @@ -405,7 +403,7 @@ getipnodebyaddr(const void *src, size_t len, int af, int *error_num) { /* * Lookup IPv6 address. */ - if (memcmp((struct in6_addr *)src, &in6addr_any, 16) == 0) { + if (memcmp((const struct in6_addr *)src, &in6addr_any, 16) == 0) { *error_num = HOST_NOT_FOUND; return (NULL); } @@ -491,7 +489,7 @@ scan_interfaces(int *have_v4, int *have_v6) { struct in_addr in4; struct in6_addr in6; char *buf = NULL, *cp, *cplim; - static int bufsiz = 4095; + static unsigned int bufsiz = 4095; int s, cpsize, n; /* Set to zero. Used as loop terminators below. */ @@ -571,7 +569,7 @@ scan_interfaces(int *have_v4, int *have_v6) { #else cpsize = sizeof lifreq.lifr_name; /* XXX maybe this should be a hard error? */ - if (ioctl(s, SOICGLIFADDR, (char *)&lifreq) < 0) + if (ioctl(s, SIOCGLIFADDR, (char *)&lifreq) < 0) continue; #endif switch (lifreq.lifr_addr.ss_family) { @@ -816,6 +814,7 @@ fakeaddr(const char *name, int af, struct net_data *net_data) { return (NULL); } pvt = net_data->ho_data; +#ifndef __bsdi__ /* * Unlike its forebear(inet_aton), our friendly inet_pton() is strict * in its interpretation of its input, and it will only return "1" if @@ -825,6 +824,15 @@ fakeaddr(const char *name, int af, struct net_data *net_data) { * This means "telnet 0xdeadbeef" and "telnet 127.1" are dead now. */ if (inet_pton(af, name, pvt->addr) != 1) { +#else + /* BSDI XXX + * We put this back to inet_aton -- we really want the old behavior + * Long live 127.1... + */ + if ((af != AF_INET || + inet_aton(name, (struct in_addr *)pvt->addr) != 1) && + inet_pton(af, name, pvt->addr) != 1) { +#endif RES_SET_H_ERRNO(net_data->res, HOST_NOT_FOUND); return (NULL); } diff --git a/contrib/bind/lib/irs/gethostent_r.c b/contrib/bind/lib/irs/gethostent_r.c index dab8639..e8017ac 100644 --- a/contrib/bind/lib/irs/gethostent_r.c +++ b/contrib/bind/lib/irs/gethostent_r.c @@ -16,7 +16,7 @@ */ #if defined(LIBC_SCCS) && !defined(lint) -static const char rcsid[] = "$Id: gethostent_r.c,v 8.5 2000/07/11 05:46:35 vixie Exp $"; +static const char rcsid[] = "$Id: gethostent_r.c,v 8.7 2001/11/01 08:02:09 marka Exp $"; #endif /* LIBC_SCCS and not lint */ #include <port_before.h> @@ -26,6 +26,7 @@ static const char rcsid[] = "$Id: gethostent_r.c,v 8.5 2000/07/11 05:46:35 vixie #include <errno.h> #include <string.h> #include <stdio.h> +#include <sys/types.h> #include <netinet/in.h> #include <netdb.h> #include <sys/param.h> @@ -39,26 +40,50 @@ copy_hostent(struct hostent *, struct hostent *, HOST_R_COPY_ARGS); HOST_R_RETURN gethostbyname_r(const char *name, struct hostent *hptr, HOST_R_ARGS) { struct hostent *he = gethostbyname(name); +#ifdef HOST_R_SETANSWER + int n = 0; +#endif HOST_R_ERRNO; +#ifdef HOST_R_SETANSWER + if (he == NULL || (n = copy_hostent(he, hptr, HOST_R_COPY)) == 0) + *answerp = NULL; + else + *answerp = hptr; + + return (n); +#else if (he == NULL) return (HOST_R_BAD); return (copy_hostent(he, hptr, HOST_R_COPY)); +#endif } HOST_R_RETURN gethostbyaddr_r(const char *addr, int len, int type, struct hostent *hptr, HOST_R_ARGS) { struct hostent *he = gethostbyaddr(addr, len, type); +#ifdef HOST_R_SETANSWER + int n = 0; +#endif HOST_R_ERRNO; +#ifdef HOST_R_SETANSWER + if (he == NULL || (n = copy_hostent(he, hptr, HOST_R_COPY)) == 0) + *answerp = NULL; + else + *answerp = hptr; + + return (n); +#else if (he == NULL) return (HOST_R_BAD); return (copy_hostent(he, hptr, HOST_R_COPY)); +#endif } /* @@ -70,13 +95,25 @@ gethostbyaddr_r(const char *addr, int len, int type, HOST_R_RETURN gethostent_r(struct hostent *hptr, HOST_R_ARGS) { struct hostent *he = gethostent(); +#ifdef HOST_R_SETANSWER + int n = 0; +#endif HOST_R_ERRNO; +#ifdef HOST_R_SETANSWER + if (he == NULL || (n = copy_hostent(he, hptr, HOST_R_COPY)) == 0) + *answerp = NULL; + else + *answerp = hptr; + + return (n); +#else if (he == NULL) return (HOST_R_BAD); return (copy_hostent(he, hptr, HOST_R_COPY)); +#endif } HOST_R_SET_RETURN @@ -96,7 +133,7 @@ HOST_R_END_RETURN #ifdef HOST_R_ENT_ARGS endhostent_r(HOST_R_ENT_ARGS) #else -endhostent_r() +endhostent_r(void) #endif { endhostent(); @@ -222,6 +259,6 @@ copy_hostent(struct hostent *he, struct hostent *hptr, HOST_R_COPY_ARGS) { } #endif /* !HOSTENT_DATA */ #else /* HOST_R_RETURN */ - static int gethostent_r_unknown_systemm = 0; + static int gethostent_r_unknown_system = 0; #endif /* HOST_R_RETURN */ #endif /* !defined(_REENTRANT) || !defined(DO_PTHREADS) */ diff --git a/contrib/bind/lib/irs/getnameinfo.c b/contrib/bind/lib/irs/getnameinfo.c index 9f186f3..0e86cc1 100644 --- a/contrib/bind/lib/irs/getnameinfo.c +++ b/contrib/bind/lib/irs/getnameinfo.c @@ -1,8 +1,6 @@ /* * Issues to be discussed: * - Thread safe-ness must be checked - * - Return values. There seems to be no standard for return value (RFC2133) - * but INRIA implementation returns EAI_xxx defined for getaddrinfo(). */ /* @@ -50,14 +48,10 @@ #include <netdb.h> #include <resolv.h> #include <string.h> +#include <stddef.h> #include <port_after.h> -#define SUCCESS 0 -#define ANY 0 -#define YES 1 -#define NO 0 - /* * Note that a_off will be dynamically adjusted so that to be consistent * with the definition of sockaddr_in{,6}. @@ -66,30 +60,30 @@ static struct afd { int a_af; int a_addrlen; - int a_socklen; + size_t a_socklen; int a_off; } afdl [] = { /* first entry is linked last... */ {PF_INET, sizeof(struct in_addr), sizeof(struct sockaddr_in), - 4 /*XXX*/}, + offsetof(struct sockaddr_in, sin_addr)}, {PF_INET6, sizeof(struct in6_addr), sizeof(struct sockaddr_in6), - 8 /*XXX*/}, - {0, 0, 0}, + offsetof(struct sockaddr_in6, sin6_addr)}, + {0, 0, 0, 0}, }; struct sockinet { +#ifdef HAVE_SA_LEN u_char si_len; +#endif u_char si_family; u_short si_port; }; -#define ENI_NOSOCKET 0 -#define ENI_NOSERVNAME 1 -#define ENI_NOHOSTNAME 2 -#define ENI_MEMORY 3 -#define ENI_SYSTEM 4 -#define ENI_FAMILY 5 -#define ENI_SALEN 6 +static int ip6_parsenumeric __P((const struct sockaddr *, const char *, char *, + size_t, int)); +#ifdef HAVE_SIN6_SCOPE_ID +static int ip6_sa2str __P((const struct sockaddr_in6 *, char *, size_t, int)); +#endif int getnameinfo(sa, salen, host, hostlen, serv, servlen, flags) @@ -106,82 +100,60 @@ getnameinfo(sa, salen, host, hostlen, serv, servlen, flags) struct hostent *hp; u_short port; #ifdef HAVE_SA_LEN - int len; + size_t len; #endif int family, i; - char *addr, *p; + const char *addr; + char *p; u_char pfx; - static int firsttime = 1; - static char numserv[512]; - static char numaddr[512]; - - - /* dynamically adjust a_off */ - if (firsttime) { - struct afd *p; - u_char *q; - struct sockaddr_in sin; - struct sockaddr_in6 sin6; - - for (p = &afdl[0]; p->a_af; p++) { - switch (p->a_af) { - case PF_INET: - q = (u_char *)&sin.sin_addr.s_addr; - p->a_off = q - (u_char *)&sin; - break; - case PF_INET6: - q = (u_char *)&sin6.sin6_addr.s6_addr; - p->a_off = q - (u_char *)&sin6; - break; - default: - break; - } - } - firsttime = 0; - } + char numserv[512]; + char numaddr[512]; if (sa == NULL) - return ENI_NOSOCKET; + return EAI_FAIL; #ifdef HAVE_SA_LEN len = sa->sa_len; - if (len != salen) return ENI_SALEN; + if (len != salen) return EAI_FAIL; #endif - + family = sa->sa_family; for (i = 0; afdl[i].a_af; i++) if (afdl[i].a_af == family) { afd = &afdl[i]; goto found; } - return ENI_FAMILY; - + return EAI_FAMILY; + found: - if (salen != afd->a_socklen) return ENI_SALEN; - - port = ((struct sockinet *)sa)->si_port; /* network byte order */ - addr = (char *)sa + afd->a_off; + if (salen != afd->a_socklen) return EAI_FAIL; + + port = ((const struct sockinet *)sa)->si_port; /* network byte order */ + addr = (const char *)sa + afd->a_off; if (serv == NULL || servlen == 0) { - /* what we should do? */ + /* + * rfc2553bis says that serv == NULL or servlen == 0 means that + * the caller does not want the result. + */ } else if (flags & NI_NUMERICSERV) { - snprintf(numserv, sizeof(numserv), "%d", ntohs(port)); + sprintf(numserv, "%d", ntohs(port)); if (strlen(numserv) > servlen) - return ENI_MEMORY; + return EAI_MEMORY; strcpy(serv, numserv); } else { sp = getservbyport(port, (flags & NI_DGRAM) ? "udp" : "tcp"); if (sp) { if (strlen(sp->s_name) + 1 > servlen) - return ENI_MEMORY; + return EAI_MEMORY; strcpy(serv, sp->s_name); } else - return ENI_NOSERVNAME; + return EAI_NONAME; } switch (sa->sa_family) { case AF_INET: - if (ntohl(*(u_long *)addr) >> IN_CLASSA_NSHIFT == 0) + if (ntohl(*(const u_long *)addr) >> IN_CLASSA_NSHIFT == 0) flags |= NI_NUMERICHOST; break; case AF_INET6: @@ -191,14 +163,12 @@ getnameinfo(sa, salen, host, hostlen, serv, servlen, flags) break; } if (host == NULL || hostlen == 0) { - /* what should we do? */ + /* + * rfc2553bis says that host == NULL or hostlen == 0 means that + * the caller does not want the result. + */ } else if (flags & NI_NUMERICHOST) { - if (inet_ntop(afd->a_af, addr, numaddr, sizeof(numaddr)) - == NULL) - return ENI_SYSTEM; - if (strlen(numaddr) + 1 > hostlen) - return ENI_MEMORY; - strcpy(host, numaddr); + goto numeric; } else { hp = gethostbyaddr(addr, afd->a_addrlen, afd->a_af); @@ -208,18 +178,130 @@ getnameinfo(sa, salen, host, hostlen, serv, servlen, flags) if (p) *p = '\0'; } if (strlen(hp->h_name) + 1 > hostlen) - return ENI_MEMORY; + return EAI_MEMORY; strcpy(host, hp->h_name); } else { if (flags & NI_NAMEREQD) - return ENI_NOHOSTNAME; - if (inet_ntop(afd->a_af, addr, numaddr, sizeof(numaddr)) - == NULL) - return ENI_NOHOSTNAME; - if (strlen(numaddr) + 1 > hostlen) - return ENI_MEMORY; - strcpy(host, numaddr); + return EAI_NONAME; + numeric: + switch(afd->a_af) { + case AF_INET6: + { + int error; + + if ((error = ip6_parsenumeric(sa, addr, host, + hostlen, + flags)) != 0) + return(error); + break; + } + + default: + if (inet_ntop(afd->a_af, addr, numaddr, + sizeof(numaddr)) == NULL) + return EAI_NONAME; + if (strlen(numaddr) + 1 > hostlen) + return EAI_MEMORY; + strcpy(host, numaddr); + } + } + } + return(0); +} + +static int +ip6_parsenumeric(const struct sockaddr *sa, const char *addr, char *host, + size_t hostlen, int flags) +{ + size_t numaddrlen; + char numaddr[512]; + +#ifndef HAVE_SIN6_SCOPE_ID + UNUSED(sa); + UNUSED(flags); +#endif + + if (inet_ntop(AF_INET6, addr, numaddr, sizeof(numaddr)) + == NULL) + return EAI_SYSTEM; + + numaddrlen = strlen(numaddr); + if (numaddrlen + 1 > hostlen) /* don't forget terminator */ + return EAI_MEMORY; + strcpy(host, numaddr); + +#ifdef HAVE_SIN6_SCOPE_ID + if (((const struct sockaddr_in6 *)sa)->sin6_scope_id) { + char scopebuf[MAXHOSTNAMELEN]; /* XXX */ + int scopelen; + + /* ip6_sa2str never fails */ + scopelen = ip6_sa2str((const struct sockaddr_in6 *)sa, + scopebuf, sizeof(scopebuf), flags); + + if (scopelen + 1 + numaddrlen + 1 > hostlen) + return EAI_MEMORY; + + /* construct <numeric-addr><delim><scopeid> */ + memcpy(host + numaddrlen + 1, scopebuf, + scopelen); + host[numaddrlen] = SCOPE_DELIMITER; + host[numaddrlen + 1 + scopelen] = '\0'; + } +#endif + + return 0; +} + +#ifdef HAVE_SIN6_SCOPE_ID +/* ARGSUSED */ +static int +ip6_sa2str(const struct sockaddr_in6 *sa6, char *buf, + size_t bufsiz, int flags) +{ +#ifdef USE_IFNAMELINKID + unsigned int ifindex = (unsigned int)sa6->sin6_scope_id; + const struct in6_addr *a6 = &sa6->sin6_addr; +#endif + char tmp[64]; + +#ifdef NI_NUMERICSCOPE + if (flags & NI_NUMERICSCOPE) { + sprintf(tmp, "%u", sa6->sin6_scope_id); + if (bufsiz != 0) { + strncpy(buf, tmp, bufsiz - 1); + buf[bufsiz - 1] = '\0'; + } + return(strlen(tmp)); + } +#endif + +#ifdef USE_IFNAMELINKID + /* + * For a link-local address, convert the index to an interface + * name, assuming a one-to-one mapping between links and interfaces. + * Note, however, that this assumption is stronger than the + * specification of the scoped address architecture; the + * specficication says that more than one interfaces can belong to + * a single link. + */ + + /* if_indextoname() does not take buffer size. not a good api... */ + if ((IN6_IS_ADDR_LINKLOCAL(a6) || IN6_IS_ADDR_MC_LINKLOCAL(a6)) && + bufsiz >= IF_NAMESIZE) { + char *p = if_indextoname(ifindex, buf); + if (p) { + return(strlen(p)); } } - return SUCCESS; +#endif + + /* last resort */ + sprintf(tmp, "%u", sa6->sin6_scope_id); + if (bufsiz != 0) { + strncpy(buf, tmp, bufsiz - 1); + buf[bufsiz - 1] = '\0'; + } + return(strlen(tmp)); } +#endif diff --git a/contrib/bind/lib/irs/getnetent.c b/contrib/bind/lib/irs/getnetent.c index 52aebe3..49810b7 100644 --- a/contrib/bind/lib/irs/getnetent.c +++ b/contrib/bind/lib/irs/getnetent.c @@ -16,7 +16,7 @@ */ #if !defined(LINT) && !defined(CODECENTER) -static const char rcsid[] = "$Id: getnetent.c,v 1.18 2000/12/23 08:14:53 vixie Exp $"; +static const char rcsid[] = "$Id: getnetent.c,v 1.19 2001/05/29 05:48:47 marka Exp $"; #endif /* Imports */ @@ -259,10 +259,11 @@ fakeaddr(const char *name, int af, struct net_data *net_data) { RES_SET_H_ERRNO(net_data->res, NETDB_INTERNAL); return (NULL); } - if (!isascii(name[0]) || !isdigit(name[0])) + if (!isascii((unsigned char)(name[0])) || + !isdigit((unsigned char)(name[0]))) return (NULL); for (cp = name; *cp; ++cp) - if (!isascii(*cp) || (!isdigit(*cp) && *cp != '.')) + if (!isascii(*cp) || (!isdigit((unsigned char)*cp) && *cp != '.')) return (NULL); if (*--cp == '.') return (NULL); diff --git a/contrib/bind/lib/irs/getnetent_r.c b/contrib/bind/lib/irs/getnetent_r.c index b78b45a..1472eb5 100644 --- a/contrib/bind/lib/irs/getnetent_r.c +++ b/contrib/bind/lib/irs/getnetent_r.c @@ -16,7 +16,7 @@ */ #if defined(LIBC_SCCS) && !defined(lint) -static const char rcsid[] = "$Id: getnetent_r.c,v 8.4 1999/01/18 07:46:52 vixie Exp $"; +static const char rcsid[] = "$Id: getnetent_r.c,v 8.6 2001/11/01 08:02:11 marka Exp $"; #endif /* LIBC_SCCS and not lint */ #include <port_before.h> @@ -26,6 +26,7 @@ static const char rcsid[] = "$Id: getnetent_r.c,v 8.4 1999/01/18 07:46:52 vixie #include <errno.h> #include <string.h> #include <stdio.h> +#include <sys/types.h> #include <netinet/in.h> #include <netdb.h> #include <sys/param.h> @@ -39,11 +40,22 @@ copy_netent(struct netent *, struct netent *, NET_R_COPY_ARGS); NET_R_RETURN getnetbyname_r(const char *name, struct netent *nptr, NET_R_ARGS) { struct netent *ne = getnetbyname(name); +#ifdef NET_R_SETANSWER + int n = 0; + if (ne == NULL || (n = copy_netent(ne, nptr, NET_R_COPY)) != 0) + *answerp = NULL; + else + *answerp = ne; + if (ne == NULL) + *h_errnop = h_errno; + return (n); +#else if (ne == NULL) return (NET_R_BAD); return (copy_netent(ne, nptr, NET_R_COPY)); +#endif } #ifndef GETNETBYADDR_ADDR_T @@ -52,11 +64,23 @@ getnetbyname_r(const char *name, struct netent *nptr, NET_R_ARGS) { NET_R_RETURN getnetbyaddr_r(GETNETBYADDR_ADDR_T addr, int type, struct netent *nptr, NET_R_ARGS) { struct netent *ne = getnetbyaddr(addr, type); +#ifdef NET_R_SETANSWER + int n = 0; + + if (ne == NULL || (n = copy_netent(ne, nptr, NET_R_COPY)) != 0) + *answerp = NULL; + else + *answerp = ne; + if (ne == NULL) + *h_errnop = h_errno; + return (n); +#else if (ne == NULL) return (NET_R_BAD); return (copy_netent(ne, nptr, NET_R_COPY)); +#endif } /* @@ -68,11 +92,23 @@ getnetbyaddr_r(GETNETBYADDR_ADDR_T addr, int type, struct netent *nptr, NET_R_AR NET_R_RETURN getnetent_r(struct netent *nptr, NET_R_ARGS) { struct netent *ne = getnetent(); +#ifdef NET_R_SETANSWER + int n = 0; + + if (ne == NULL || (n = copy_netent(ne, nptr, NET_R_COPY)) != 0) + *answerp = NULL; + else + *answerp = ne; + if (ne == NULL) + *h_errnop = h_errno; + return (n); +#else if (ne == NULL) return (NET_R_BAD); return (copy_netent(ne, nptr, NET_R_COPY)); +#endif } NET_R_SET_RETURN @@ -117,7 +153,7 @@ copy_netent(struct netent *ne, struct netent *nptr, NET_R_COPY_ARGS) { len += strlen(ne->n_name) + 1; len += numptr * sizeof(char*); - if (len > buflen) { + if (len > (int)buflen) { errno = ERANGE; return (NET_R_BAD); } @@ -186,6 +222,6 @@ copy_netent(struct netent *ne, struct netent *nptr, NET_R_COPY_ARGS) { } #endif /* !NETENT_DATA */ #else /* NET_R_RETURN */ - static int getnetent_r_unknown_systemm = 0; + static int getnetent_r_unknown_system = 0; #endif /* NET_R_RETURN */ #endif /* !defined(_REENTRANT) || !defined(DO_PTHREADS) */ diff --git a/contrib/bind/lib/irs/getnetgrent.c b/contrib/bind/lib/irs/getnetgrent.c index 8c5f5f8..e966ea6 100644 --- a/contrib/bind/lib/irs/getnetgrent.c +++ b/contrib/bind/lib/irs/getnetgrent.c @@ -16,7 +16,7 @@ */ #if defined(LIBC_SCCS) && !defined(lint) -static const char rcsid[] = "$Id: getnetgrent.c,v 1.14 1999/10/07 20:44:03 vixie Exp $"; +static const char rcsid[] = "$Id: getnetgrent.c,v 1.15 2001/05/29 05:48:49 marka Exp $"; #endif /* LIBC_SCCS and not lint */ /* Imports */ @@ -70,7 +70,7 @@ innetgr(const char *netgroup, const char *host, } int -getnetgrent(char **host, char **user, char **domain) { +getnetgrent(const char **host, const char **user, const char **domain) { struct net_data *net_data = init(); return (getnetgrent_p(host, user, domain, net_data)); @@ -109,7 +109,7 @@ innetgr_p(const char *netgroup, const char *host, } int -getnetgrent_p(char **host, char **user, char **domain, +getnetgrent_p(const char **host, const char **user, const char **domain, struct net_data *net_data ) { struct irs_ng *ng; diff --git a/contrib/bind/lib/irs/getnetgrent_r.c b/contrib/bind/lib/irs/getnetgrent_r.c index e0c366c..adae817 100644 --- a/contrib/bind/lib/irs/getnetgrent_r.c +++ b/contrib/bind/lib/irs/getnetgrent_r.c @@ -16,7 +16,7 @@ */ #if defined(LIBC_SCCS) && !defined(lint) -static const char rcsid[] = "$Id: getnetgrent_r.c,v 8.4 1999/01/18 07:46:52 vixie Exp $"; +static const char rcsid[] = "$Id: getnetgrent_r.c,v 8.6 2001/11/01 08:02:12 marka Exp $"; #endif /* LIBC_SCCS and not lint */ #include <port_before.h> @@ -26,15 +26,18 @@ static const char rcsid[] = "$Id: getnetgrent_r.c,v 8.4 1999/01/18 07:46:52 vixi #include <errno.h> #include <string.h> #include <stdio.h> +#include <sys/types.h> #include <netinet/in.h> #include <netdb.h> +#include <netgroup.h> +#include <stdlib.h> #include <port_after.h> #ifdef NGR_R_RETURN static NGR_R_RETURN -copy_protoent(char **, char **, char **, char *, char *, char *, - NGR_R_COPY_ARGS); +copy_protoent(char **, char **, char **, const char *, const char *, + const char *, NGR_R_COPY_ARGS); NGR_R_RETURN innetgr_r(const char *netgroup, const char *host, const char *user, @@ -51,7 +54,7 @@ innetgr_r(const char *netgroup, const char *host, const char *user, NGR_R_RETURN getnetgrent_r(char **machinep, char **userp, char **domainp, NGR_R_ARGS) { - char *mp, *up, *dp; + const char *mp, *up, *dp; int res = getnetgrent(&mp, &up, &dp); if (res != 1) @@ -69,14 +72,27 @@ setnetgrent_r(const char *netgroup) #endif { setnetgrent(netgroup); +#ifdef NGR_R_PRIVATE + *buf = NULL; +#endif #ifdef NGR_R_SET_RESULT return (NGR_R_SET_RESULT); #endif } NGR_R_END_RETURN -endnetgrent_r(NGR_R_ENT_ARGS) { +#ifdef NGR_R_ENT_ARGS +endnetgrent_r(NGR_R_ENT_ARGS) +#else +endnetgrent_r(void) +#endif +{ endnetgrent(); +#ifdef NGR_R_PRIVATE + if (*buf != NULL) + free(*buf); + *buf = NULL; +#endif NGR_R_END_RESULT(NGR_R_OK); } @@ -84,9 +100,10 @@ endnetgrent_r(NGR_R_ENT_ARGS) { static int copy_protoent(char **machinep, char **userp, char **domainp, - char *mp, char *up, char *dp, NGR_R_COPY_ARGS) { + const char *mp, const char *up, const char *dp, + NGR_R_COPY_ARGS) { char *cp; - int i, n; + int n; int len; /* Find out the amount of space required to store the answer. */ @@ -95,12 +112,20 @@ copy_protoent(char **machinep, char **userp, char **domainp, if (up != NULL) len += strlen(up) + 1; if (dp != NULL) len += strlen(dp) + 1; - if (len > buflen) { +#ifdef NGR_R_PRIVATE + free(*buf); + *buf = malloc(len); + if (*buf == NULL) + return(NGR_R_BAD); + cp = *buf; +#else + if (len > (int)buflen) { errno = ERANGE; return (NGR_R_BAD); } - cp = buf; +#endif + if (mp != NULL) { n = strlen(mp) + 1; diff --git a/contrib/bind/lib/irs/getprotoent.c b/contrib/bind/lib/irs/getprotoent.c index e3bfc37..724b0ad 100644 --- a/contrib/bind/lib/irs/getprotoent.c +++ b/contrib/bind/lib/irs/getprotoent.c @@ -16,7 +16,7 @@ */ #if !defined(LINT) && !defined(CODECENTER) -static const char rcsid[] = "$Id: getprotoent.c,v 1.15 1999/10/13 16:39:31 vixie Exp $"; +static const char rcsid[] = "$Id: getprotoent.c,v 1.16 2001/11/01 07:34:33 marka Exp $"; #endif /* Imports */ @@ -33,6 +33,7 @@ static const char rcsid[] = "$Id: getprotoent.c,v 1.15 1999/10/13 16:39:31 vixie #include <errno.h> #include <resolv.h> #include <stdio.h> +#include <string.h> #include <irs.h> diff --git a/contrib/bind/lib/irs/getprotoent_r.c b/contrib/bind/lib/irs/getprotoent_r.c index e5c54d7..fc3b17e 100644 --- a/contrib/bind/lib/irs/getprotoent_r.c +++ b/contrib/bind/lib/irs/getprotoent_r.c @@ -16,7 +16,7 @@ */ #if defined(LIBC_SCCS) && !defined(lint) -static const char rcsid[] = "$Id: getprotoent_r.c,v 8.4 1999/01/18 07:46:52 vixie Exp $"; +static const char rcsid[] = "$Id: getprotoent_r.c,v 8.6 2001/11/01 08:02:14 marka Exp $"; #endif /* LIBC_SCCS and not lint */ #include <port_before.h> @@ -26,6 +26,7 @@ static const char rcsid[] = "$Id: getprotoent_r.c,v 8.4 1999/01/18 07:46:52 vixi #include <errno.h> #include <string.h> #include <stdio.h> +#include <sys/types.h> #include <netinet/in.h> #include <netdb.h> #include <port_after.h> @@ -38,21 +39,41 @@ copy_protoent(struct protoent *, struct protoent *, PROTO_R_COPY_ARGS); PROTO_R_RETURN getprotobyname_r(const char *name, struct protoent *pptr, PROTO_R_ARGS) { struct protoent *pe = getprotobyname(name); +#ifdef PROTO_R_SETANSWER + int n = 0; + if (pe == NULL || (n = copy_protoent(pe, pptr, PROTO_R_COPY)) != 0) + *answerp = NULL; + else + *answerp = pptr; + + return (n); +#else if (pe == NULL) return (PROTO_R_BAD); return (copy_protoent(pe, pptr, PROTO_R_COPY)); +#endif } PROTO_R_RETURN getprotobynumber_r(int proto, struct protoent *pptr, PROTO_R_ARGS) { struct protoent *pe = getprotobynumber(proto); +#ifdef PROTO_R_SETANSWER + int n = 0; + if (pe == NULL || (n = copy_protoent(pe, pptr, PROTO_R_COPY)) != 0) + *answerp = NULL; + else + *answerp = pptr; + + return (n); +#else if (pe == NULL) return (PROTO_R_BAD); return (copy_protoent(pe, pptr, PROTO_R_COPY)); +#endif } /* @@ -64,11 +85,21 @@ getprotobynumber_r(int proto, struct protoent *pptr, PROTO_R_ARGS) { PROTO_R_RETURN getprotoent_r(struct protoent *pptr, PROTO_R_ARGS) { struct protoent *pe = getprotoent(); +#ifdef PROTO_R_SETANSWER + int n = 0; + if (pe == NULL || (n = copy_protoent(pe, pptr, PROTO_R_COPY)) != 0) + *answerp = NULL; + else + *answerp = pptr; + + return (n); +#else if (pe == NULL) return (PROTO_R_BAD); return (copy_protoent(pe, pptr, PROTO_R_COPY)); +#endif } PROTO_R_SET_RETURN @@ -113,7 +144,7 @@ copy_protoent(struct protoent *pe, struct protoent *pptr, PROTO_R_COPY_ARGS) { len += strlen(pe->p_name) + 1; len += numptr * sizeof(char*); - if (len > buflen) { + if (len > (int)buflen) { errno = ERANGE; return (PROTO_R_BAD); } @@ -180,6 +211,6 @@ copy_protoent(struct protoent *pe, struct protoent *pptr, PROTO_R_COPY_ARGS) { } #endif /* PROTOENT_DATA */ #else /* PROTO_R_RETURN */ - static int getprotoent_r_unknown_systemm = 0; + static int getprotoent_r_unknown_system = 0; #endif /* PROTO_R_RETURN */ #endif /* !defined(_REENTRANT) || !defined(DO_PTHREADS) */ diff --git a/contrib/bind/lib/irs/getpwent_r.c b/contrib/bind/lib/irs/getpwent_r.c index 761fa45..ee2d8a7 100644 --- a/contrib/bind/lib/irs/getpwent_r.c +++ b/contrib/bind/lib/irs/getpwent_r.c @@ -16,7 +16,7 @@ */ #if defined(LIBC_SCCS) && !defined(lint) -static const char rcsid[] = "$Id: getpwent_r.c,v 8.3 1999/01/08 19:24:33 vixie Exp $"; +static const char rcsid[] = "$Id: getpwent_r.c,v 8.6 2001/11/01 08:02:15 marka Exp $"; #endif /* LIBC_SCCS and not lint */ #include <port_before.h> @@ -27,7 +27,19 @@ static const char rcsid[] = "$Id: getpwent_r.c,v 8.3 1999/01/08 19:24:33 vixie E #include <string.h> #include <stdio.h> #include <sys/types.h> +#if (defined(POSIX_GETPWNAM_R) || defined(POSIX_GETPWUID_R)) +#if defined(_POSIX_PTHREAD_SEMANTICS) + /* turn off solaris remapping in <grp.h> */ +#undef _POSIX_PTHREAD_SEMANTICS #include <pwd.h> +#define _POSIX_PTHREAD_SEMANTICS 1 +#else +#define _UNIX95 1 +#include <pwd.h> +#endif +#else +#include <pwd.h> +#endif #include <port_after.h> #ifdef PASS_R_RETURN @@ -50,7 +62,7 @@ getpwnam_r(const char *login, struct passwd *pwptr, if (pw == NULL) { *result = NULL; - return (-1); + return (0); } res = copy_passwd(pw, pwptr, buf, buflen); @@ -87,7 +99,7 @@ getpwuid_r(uid_t uid, struct passwd *pwptr, if (pw == NULL) { *result = NULL; - return (-1); + return (0); } res = copy_passwd(pw, pwptr, buf, buflen); @@ -142,7 +154,12 @@ setpassent_r(int stayopen) } PASS_R_SET_RETURN -setpwent_r(PASS_R_ENT_ARGS) { +#ifdef PASS_R_ENT_ARGS +setpwent_r(PASS_R_ENT_ARGS) +#else +setpwent_r(void) +#endif +{ setpwent(); #ifdef PASS_R_SET_RESULT @@ -151,7 +168,12 @@ setpwent_r(PASS_R_ENT_ARGS) { } PASS_R_END_RETURN -endpwent_r(PASS_R_ENT_ARGS) { +#ifdef PASS_R_ENT_ARGS +endpwent_r(PASS_R_ENT_ARGS) +#else +endpwent_r(void) +#endif +{ endpwent(); PASS_R_END_RESULT(PASS_R_OK); @@ -177,8 +199,8 @@ fgetpwent_r(FILE *f, struct passwd *pwptr, PASS_R_COPY_ARGS) { static int copy_passwd(struct passwd *pw, struct passwd *pwptr, char *buf, int buflen) { char *cp; - int i, n; - int numptr, len; + int n; + int len; /* Find out the amount of space required to store the answer. */ len = strlen(pw->pw_name) + 1; @@ -192,7 +214,7 @@ copy_passwd(struct passwd *pw, struct passwd *pwptr, char *buf, int buflen) { if (len > buflen) { errno = ERANGE; - return (-1); + return (ERANGE); } /* copy fixed atomic values*/ @@ -248,6 +270,6 @@ copy_passwd(struct passwd *pw, struct passwd *pwptr, char *buf, int buflen) { return (0); } #else /* PASS_R_RETURN */ - static int getpwent_r_unknown_systemm = 0; + static int getpwent_r_unknown_system = 0; #endif /* PASS_R_RETURN */ #endif /* !def(_REENTRANT) || !def(DO_PTHREADS) || !def(WANT_IRS_PW) */ diff --git a/contrib/bind/lib/irs/getservent.c b/contrib/bind/lib/irs/getservent.c index d2b8b50..d63ae1d 100644 --- a/contrib/bind/lib/irs/getservent.c +++ b/contrib/bind/lib/irs/getservent.c @@ -16,7 +16,7 @@ */ #if !defined(LINT) && !defined(CODECENTER) -static const char rcsid[] = "$Id: getservent.c,v 1.16 1999/10/13 16:39:31 vixie Exp $"; +static const char rcsid[] = "$Id: getservent.c,v 1.17 2001/11/01 07:33:16 marka Exp $"; #endif /* Imports */ @@ -33,6 +33,7 @@ static const char rcsid[] = "$Id: getservent.c,v 1.16 1999/10/13 16:39:31 vixie #include <errno.h> #include <resolv.h> #include <stdio.h> +#include <string.h> #include <irs.h> diff --git a/contrib/bind/lib/irs/getservent_r.c b/contrib/bind/lib/irs/getservent_r.c index 4da9dc2..b4897ae 100644 --- a/contrib/bind/lib/irs/getservent_r.c +++ b/contrib/bind/lib/irs/getservent_r.c @@ -16,7 +16,7 @@ */ #if defined(LIBC_SCCS) && !defined(lint) -static const char rcsid[] = "$Id: getservent_r.c,v 8.3 1999/01/08 19:24:36 vixie Exp $"; +static const char rcsid[] = "$Id: getservent_r.c,v 8.5 2001/11/01 08:02:16 marka Exp $"; #endif /* LIBC_SCCS and not lint */ #include <port_before.h> @@ -26,6 +26,7 @@ static const char rcsid[] = "$Id: getservent_r.c,v 8.3 1999/01/08 19:24:36 vixie #include <errno.h> #include <string.h> #include <stdio.h> +#include <sys/types.h> #include <netinet/in.h> #include <netdb.h> #include <sys/param.h> @@ -40,22 +41,42 @@ SERV_R_RETURN getservbyname_r(const char *name, const char *proto, struct servent *sptr, SERV_R_ARGS) { struct servent *se = getservbyname(name, proto); +#ifdef SERV_R_SETANSWER + int n = 0; + + if (se == NULL || (n = copy_servent(se, sptr, SERV_R_COPY)) != 0) + *answerp = NULL; + else + *answerp = sptr; + return (n); +#else if (se == NULL) return (SERV_R_BAD); return (copy_servent(se, sptr, SERV_R_COPY)); +#endif } SERV_R_RETURN getservbyport_r(int port, const char *proto, struct servent *sptr, SERV_R_ARGS) { struct servent *se = getservbyport(port, proto); +#ifdef SERV_R_SETANSWER + int n = 0; + + if (se == NULL || (n = copy_servent(se, sptr, SERV_R_COPY)) != 0) + *answerp = NULL; + else + *answerp = sptr; + return (n); +#else if (se == NULL) return (SERV_R_BAD); return (copy_servent(se, sptr, SERV_R_COPY)); +#endif } /* @@ -67,11 +88,21 @@ getservbyport_r(int port, const char *proto, SERV_R_RETURN getservent_r(struct servent *sptr, SERV_R_ARGS) { struct servent *se = getservent(); +#ifdef SERV_R_SETANSWER + int n = 0; + + if (se == NULL || (n = copy_servent(se, sptr, SERV_R_COPY)) != 0) + *answerp = NULL; + else + *answerp = sptr; + return (n); +#else if (se == NULL) return (SERV_R_BAD); return (copy_servent(se, sptr, SERV_R_COPY)); +#endif } SERV_R_SET_RETURN @@ -119,7 +150,7 @@ copy_servent(struct servent *se, struct servent *sptr, SERV_R_COPY_ARGS) { len += strlen(se->s_proto) + 1; len += numptr * sizeof(char*); - if (len > buflen) { + if (len > (int)buflen) { errno = ERANGE; return (SERV_R_BAD); } @@ -201,6 +232,6 @@ copy_servent(struct servent *se, struct servent *sptr, SERV_R_COPY_ARGS) { } #endif /* !SERVENT_DATA */ #else /*SERV_R_RETURN */ - static int getservent_r_unknown_systemm = 0; + static int getservent_r_unknown_system = 0; #endif /*SERV_R_RETURN */ #endif /* !defined(_REENTRANT) || !defined(DO_PTHREADS) */ diff --git a/contrib/bind/lib/irs/hesiod.c b/contrib/bind/lib/irs/hesiod.c index 40826eb..2b08911 100644 --- a/contrib/bind/lib/irs/hesiod.c +++ b/contrib/bind/lib/irs/hesiod.c @@ -1,5 +1,5 @@ #if defined(LIBC_SCCS) && !defined(lint) -static const char rcsid[] = "$Id: hesiod.c,v 1.21 2000/02/28 14:51:08 vixie Exp $"; +static const char rcsid[] = "$Id: hesiod.c,v 1.22 2001/05/29 05:48:55 marka Exp $"; #endif /* @@ -259,6 +259,8 @@ void hesiod_free_list(void *context, char **list) { char **p; + UNUSED(context); + for (p = list; *p; p++) free(*p); free(list); diff --git a/contrib/bind/lib/irs/irp.c b/contrib/bind/lib/irs/irp.c index a6c8f4f..fa28b3f 100644 --- a/contrib/bind/lib/irs/irp.c +++ b/contrib/bind/lib/irs/irp.c @@ -16,7 +16,7 @@ */ #if !defined(LINT) && !defined(CODECENTER) -static const char rcsid[] = "$Id: irp.c,v 8.6 2000/02/04 08:28:33 vixie Exp $"; +static const char rcsid[] = "$Id: irp.c,v 8.8 2001/09/25 04:50:29 marka Exp $"; #endif /* Imports */ @@ -84,6 +84,8 @@ irs_irp_acc(const char *options) { struct irs_acc *acc; struct irp_p *irp; + UNUSED(options); + if (!(acc = memget(sizeof *acc))) { errno = ENOMEM; return (NULL); @@ -387,9 +389,9 @@ irs_irp_read_response(struct irp_p *pvt, char *text, size_t textlen) { code = 0; } else if (text != NULL && textlen > 0) { p = line; - while (isspace(*p)) p++; - while (isdigit(*p)) p++; - while (isspace(*p)) p++; + while (isspace((unsigned char)*p)) p++; + while (isdigit((unsigned char)*p)) p++; + while (isspace((unsigned char)*p)) p++; strncpy(text, p, textlen - 1); p[textlen - 1] = '\0'; } @@ -537,7 +539,8 @@ irs_irp_send_command(struct irp_p *pvt, const char *fmt, ...) { va_start(ap, fmt); todo = vsprintf(buffer, fmt, ap); - if (todo > sizeof buffer - 2) { + va_end(ap); + if (todo > (int)sizeof(buffer) - 3) { syslog(LOG_CRIT, "memory overrun in irs_irp_send_command()"); exit(1); } @@ -559,7 +562,6 @@ irs_irp_send_command(struct irp_p *pvt, const char *fmt, ...) { } todo -= i; } - va_end(ap); return (0); } diff --git a/contrib/bind/lib/irs/irp_gr.c b/contrib/bind/lib/irs/irp_gr.c index 4e2a28c..c235e19 100644 --- a/contrib/bind/lib/irs/irp_gr.c +++ b/contrib/bind/lib/irs/irp_gr.c @@ -16,7 +16,7 @@ */ #if defined(LIBC_SCCS) && !defined(lint) -static const char rcsid[] = "$Id: irp_gr.c,v 8.1 1999/01/18 07:46:53 vixie Exp $"; +static const char rcsid[] = "$Id: irp_gr.c,v 8.3 2001/05/29 05:48:57 marka Exp $"; #endif /* LIBC_SCCS and not lint */ /* extern */ @@ -285,7 +285,7 @@ gr_bygid(struct irs_gr *this, gid_t gid) { int code; char text[256]; - if (gr->gr_name != NULL && gr->gr_gid == gid) { + if (gr->gr_name != NULL && (gid_t)gr->gr_gid == gid) { return (gr); } @@ -397,6 +397,9 @@ free_group(struct group *gr) { for (p = gr->gr_mem ; p != NULL && *p != NULL ; p++) free(*p); + if (gr->gr_mem) + free(gr->gr_mem); + if (p != NULL) free(p); } diff --git a/contrib/bind/lib/irs/irp_ho.c b/contrib/bind/lib/irs/irp_ho.c index 7bfd0e2..2124017 100644 --- a/contrib/bind/lib/irs/irp_ho.c +++ b/contrib/bind/lib/irs/irp_ho.c @@ -16,7 +16,7 @@ */ #if defined(LIBC_SCCS) && !defined(lint) -static const char rcsid[] = "$Id: irp_ho.c,v 8.2 1999/10/13 16:39:31 vixie Exp $"; +static const char rcsid[] = "$Id: irp_ho.c,v 8.3 2001/05/29 05:48:59 marka Exp $"; #endif /* LIBC_SCCS and not lint */ /* Imports. */ @@ -79,7 +79,8 @@ static void ho_rewind(struct irs_ho *this); static void ho_minimize(struct irs_ho *this); static void free_host(struct hostent *ho); - +static struct addrinfo * ho_addrinfo(struct irs_ho *this, const char *name, + const struct addrinfo *pai); /* Public. */ @@ -121,6 +122,7 @@ irs_irp_ho(struct irs_acc *this) { ho->next = ho_next; ho->rewind = ho_rewind; ho->minimize = ho_minimize; + ho->addrinfo = ho_addrinfo; return (ho); } @@ -416,3 +418,12 @@ free_host(struct hostent *ho) { } } +/* dummy */ +static struct addrinfo * +ho_addrinfo(struct irs_ho *this, const char *name, const struct addrinfo *pai) +{ + UNUSED(this); + UNUSED(name); + UNUSED(pai); + return(NULL); +} diff --git a/contrib/bind/lib/irs/irp_ng.c b/contrib/bind/lib/irs/irp_ng.c index e96f66c..b3cf0f4 100644 --- a/contrib/bind/lib/irs/irp_ng.c +++ b/contrib/bind/lib/irs/irp_ng.c @@ -16,7 +16,7 @@ */ #if !defined(LINT) && !defined(CODECENTER) -static const char rcsid[] = "$Id: irp_ng.c,v 8.2 1999/10/13 16:39:31 vixie Exp $"; +static const char rcsid[] = "$Id: irp_ng.c,v 8.3 2001/05/29 05:49:00 marka Exp $"; #endif /* Imports */ @@ -52,7 +52,8 @@ struct pvt { static void ng_rewind(struct irs_ng *, const char*); static void ng_close(struct irs_ng *); -static int ng_next(struct irs_ng *, char **, char **, char **); +static int ng_next(struct irs_ng *, const char **, const char **, + const char **); static int ng_test(struct irs_ng *, const char *, const char *, const char *, const char *); @@ -158,7 +159,8 @@ ng_rewind(struct irs_ng *this, const char *group) { /* - * int ng_next(struct irs_ng *this, char **host, char **user, char **domain) + * int ng_next(struct irs_ng *this, const char **host, const char **user, + * const char **domain) * * Notes: * @@ -167,7 +169,9 @@ ng_rewind(struct irs_ng *this, const char *group) { */ static int -ng_next(struct irs_ng *this, char **host, char **user, char **domain) { +ng_next(struct irs_ng *this, const char **host, const char **user, + const char **domain) +{ struct pvt *pvt = (struct pvt *)this->private; int code; char *body = NULL; @@ -224,6 +228,8 @@ ng_test(struct irs_ng *this, const char *name, char text[256]; int rval = 0; + UNUSED(name); + if (irs_irp_connection_setup(pvt->girpdata, &pvt->warned) != 0) { return (0); } diff --git a/contrib/bind/lib/irs/irp_p.h b/contrib/bind/lib/irs/irp_p.h index adf8174..0f68b28 100644 --- a/contrib/bind/lib/irs/irp_p.h +++ b/contrib/bind/lib/irs/irp_p.h @@ -16,7 +16,7 @@ */ /* - * $Id: irp_p.h,v 8.1 1999/01/18 07:46:54 vixie Exp $ + * $Id: irp_p.h,v 8.2 2001/08/10 02:40:52 marka Exp $ */ #ifndef _IRP_P_H_INCLUDED @@ -53,7 +53,7 @@ char *irs_irp_read_body(struct irp_p *pvt, size_t *size); int irs_irp_get_full_response(struct irp_p *pvt, int *code, char *text, size_t textlen, char **body, size_t *bodylen); -int irs_irp_send_command(struct irp_p *pvt, const char *fmt, ...); +int irs_irp_send_command(struct irp_p *pvt, const char *fmt, ...) ISC_FORMAT_PRINTF(2, 3); extern int irp_log_errors; diff --git a/contrib/bind/lib/irs/irp_pw.c b/contrib/bind/lib/irs/irp_pw.c index f23cb73..b659caa 100644 --- a/contrib/bind/lib/irs/irp_pw.c +++ b/contrib/bind/lib/irs/irp_pw.c @@ -16,7 +16,7 @@ */ #if defined(LIBC_SCCS) && !defined(lint) -static const char rcsid[] = "$Id: irp_pw.c,v 8.1 1999/01/18 07:46:54 vixie Exp $"; +static const char rcsid[] = "$Id: irp_pw.c,v 8.2 2001/11/01 07:29:26 marka Exp $"; #endif /* LIBC_SCCS and not lint */ /* Extern */ @@ -340,8 +340,10 @@ free_passwd(struct passwd *pw) { if (pw->pw_passwd != NULL) free(pw->pw_passwd); +#ifdef HAVE_PW_CLASS if (pw->pw_class != NULL) free(pw->pw_class); +#endif if (pw->pw_gecos != NULL) free(pw->pw_gecos); diff --git a/contrib/bind/lib/irs/irpmarshall.c b/contrib/bind/lib/irs/irpmarshall.c index 240bb08..6331ce1 100644 --- a/contrib/bind/lib/irs/irpmarshall.c +++ b/contrib/bind/lib/irs/irpmarshall.c @@ -49,7 +49,7 @@ */ #if defined(LIBC_SCCS) && !defined(lint) -static const char rcsid[] = "$Id: irpmarshall.c,v 8.6 2000/11/13 05:08:08 vixie Exp $"; +static const char rcsid[] = "$Id: irpmarshall.c,v 8.7 2001/05/29 05:49:01 marka Exp $"; #endif /* LIBC_SCCS and not lint */ #if 0 @@ -139,7 +139,7 @@ irp_marshall_pw(const struct passwd *pw, char **buffer, size_t *len) { char pwGid[24]; char pwChange[24]; char pwExpire[24]; - char *pwClass; + const char *pwClass; const char *fieldsep = COLONSTR; if (pw == NULL || len == NULL) { @@ -1228,8 +1228,8 @@ irp_marshall_ng(const char *host, const char *user, const char *domain, /* - * int irp_unmarshall_ng(char **host, char **user, char **domain, - * char *buffer) + * int irp_unmarshall_ng(const char **host, const char **user, + * const char **domain, char *buffer) * * notes: * @@ -1243,20 +1243,24 @@ irp_marshall_ng(const char *host, const char *user, const char *domain, */ int -irp_unmarshall_ng(char **host, char **user, char **domain, char *buffer) { +irp_unmarshall_ng(const char **hostp, const char **userp, const char **domainp, + char *buffer) +{ char *p, *q; char fieldsep = ','; int myerrno = EINVAL; + char *host, *user, *domain; - if (user == NULL || host == NULL || domain == NULL || buffer == NULL) { + if (userp == NULL || hostp == NULL || + domainp == NULL || buffer == NULL) { errno = EINVAL; return (-1); } - *host = *user = *domain = NULL; + host = user = domain = NULL; p = buffer; - while (isspace(*p)) { + while (isspace((unsigned char)*p)) { p++; } if (*p != '(') { @@ -1269,7 +1273,7 @@ irp_unmarshall_ng(char **host, char **user, char **domain, char *buffer) { if (!*q) { goto error; } else if (q > p + 1) { - *host = strndup(p, q - p); + host = strndup(p, q - p); } p = q + 1; @@ -1282,7 +1286,7 @@ irp_unmarshall_ng(char **host, char **user, char **domain, char *buffer) { if (!*q) { goto error; } - *user = strndup(p, q - p); + user = strndup(p, q - p); } else { p++; } @@ -1296,17 +1300,20 @@ irp_unmarshall_ng(char **host, char **user, char **domain, char *buffer) { if (!*q) { goto error; } - *domain = strndup(p, q - p); + domain = strndup(p, q - p); } + *hostp = host; + *userp = user; + *domainp = domain; return (0); error: errno = myerrno; - if (*host != NULL) free(*host); - if (*user != NULL) free(*user); - if (*domain != NULL) free(*domain); + if (host != NULL) free(host); + if (user != NULL) free(user); + if (domain != NULL) free(domain); return (-1); } @@ -1847,7 +1854,7 @@ getfield(char **res, size_t reslen, char **ptr, char delim) { if (*res == NULL) { *res = strndup(*ptr, q - *ptr); } else { - if (q - *ptr + 1 > reslen) { /* to big for res */ + if ((size_t)(q - *ptr + 1) > reslen) { /* to big for res */ errno = EINVAL; return (NULL); } else { diff --git a/contrib/bind/lib/irs/irs_data.c b/contrib/bind/lib/irs/irs_data.c index 8446c6b..000da0c 100644 --- a/contrib/bind/lib/irs/irs_data.c +++ b/contrib/bind/lib/irs/irs_data.c @@ -16,7 +16,7 @@ */ #if !defined(LINT) && !defined(CODECENTER) -static const char rcsid[] = "$Id: irs_data.c,v 1.15 2000/12/23 08:14:54 vixie Exp $"; +static const char rcsid[] = "$Id: irs_data.c,v 1.19 2001/08/20 07:08:41 marka Exp $"; #endif #include "port_before.h" @@ -30,6 +30,7 @@ static const char rcsid[] = "$Id: irs_data.c,v 1.15 2000/12/23 08:14:54 vixie Ex #include <resolv.h> #include <stdio.h> +#include <string.h> #include <isc/memcluster.h> #ifdef DO_PTHREADS @@ -67,7 +68,7 @@ void net_data_destroy(void *p) { struct net_data *net_data = p; - res_nclose(net_data->res); + res_ndestroy(net_data->res); if (net_data->gr != NULL) { (*net_data->gr->close)(net_data->gr); net_data->gr = NULL; @@ -152,7 +153,8 @@ net_data_create(const char *conf_file) { if (net_data->res == NULL) return (NULL); - if (res_ninit(net_data->res) == -1) + if ((net_data->res->options & RES_INIT) == 0 && + res_ninit(net_data->res) == -1) return (NULL); return (net_data); @@ -165,6 +167,7 @@ net_data_minimize(struct net_data *net_data) { res_nclose(net_data->res); } +#ifdef _REENTRANT struct __res_state * __res_state(void) { /* NULL param here means use the default config file. */ @@ -174,6 +177,7 @@ __res_state(void) { return (&_res); } +#endif int * __h_errno(void) { diff --git a/contrib/bind/lib/irs/lcl.c b/contrib/bind/lib/irs/lcl.c index 16e167f..ed9e6b4 100644 --- a/contrib/bind/lib/irs/lcl.c +++ b/contrib/bind/lib/irs/lcl.c @@ -16,7 +16,7 @@ */ #if !defined(LINT) && !defined(CODECENTER) -static const char rcsid[] = "$Id: lcl.c,v 1.16 2000/02/28 07:52:16 vixie Exp $"; +static const char rcsid[] = "$Id: lcl.c,v 1.17 2001/05/29 05:49:02 marka Exp $"; #endif /* Imports */ @@ -55,6 +55,8 @@ irs_lcl_acc(const char *options) { struct irs_acc *acc; struct lcl_p *lcl; + UNUSED(options); + if (!(acc = memget(sizeof *acc))) { errno = ENOMEM; return (NULL); diff --git a/contrib/bind/lib/irs/lcl_gr.c b/contrib/bind/lib/irs/lcl_gr.c index acb85ee..7536c27 100644 --- a/contrib/bind/lib/irs/lcl_gr.c +++ b/contrib/bind/lib/irs/lcl_gr.c @@ -49,7 +49,7 @@ */ #if defined(LIBC_SCCS) && !defined(lint) -static const char rcsid[] = "$Id: lcl_gr.c,v 1.25 1999/10/13 17:11:19 vixie Exp $"; +static const char rcsid[] = "$Id: lcl_gr.c,v 1.26 2001/05/29 05:49:03 marka Exp $"; /* from getgrent.c 8.2 (Berkeley) 3/21/94"; */ /* from BSDI Id: getgrent.c,v 2.8 1996/05/28 18:15:14 bostic Exp $ */ #endif /* LIBC_SCCS and not lint */ @@ -129,6 +129,8 @@ irs_lcl_gr(struct irs_acc *this) { struct irs_gr *gr; struct pvt *pvt; + UNUSED(this); + if (!(gr = memget(sizeof *gr))) { errno = ENOMEM; return (NULL); @@ -313,7 +315,7 @@ grscan(struct irs_gr *this, int search, gid_t gid, const char *name) { continue; } pvt->group.gr_gid = atoi(p); - if (search && name == NULL && pvt->group.gr_gid != gid) + if (search && name == NULL && (gid_t)pvt->group.gr_gid != gid) continue; /* We want this record. */ diff --git a/contrib/bind/lib/irs/lcl_ho.c b/contrib/bind/lib/irs/lcl_ho.c index 5939207..e9685a3 100644 --- a/contrib/bind/lib/irs/lcl_ho.c +++ b/contrib/bind/lib/irs/lcl_ho.c @@ -52,7 +52,7 @@ /* BIND Id: gethnamaddr.c,v 8.15 1996/05/22 04:56:30 vixie Exp $ */ #if defined(LIBC_SCCS) && !defined(lint) -static const char rcsid[] = "$Id: lcl_ho.c,v 1.25 1999/10/13 17:11:19 vixie Exp $"; +static const char rcsid[] = "$Id: lcl_ho.c,v 1.26 2001/05/29 05:49:04 marka Exp $"; #endif /* LIBC_SCCS and not lint */ /* Imports. */ @@ -83,6 +83,7 @@ static const char rcsid[] = "$Id: lcl_ho.c,v 1.25 1999/10/13 17:11:19 vixie Exp #include "irs_p.h" #include "dns_p.h" +#include "lcl_p.h" #ifdef SPRINTF_CHAR # define SPRINTF(x) strlen(sprintf/**/x) @@ -136,6 +137,8 @@ static struct __res_state * ho_res_get(struct irs_ho *this); static void ho_res_set(struct irs_ho *this, struct __res_state *res, void (*free_res)(void *)); +static struct addrinfo * ho_addrinfo(struct irs_ho *this, const char *name, + const struct addrinfo *pai); static size_t ns_namelen(const char *); static int init(struct irs_ho *this); @@ -153,6 +156,8 @@ irs_lcl_ho(struct irs_acc *this) { struct irs_ho *ho; struct pvt *pvt; + UNUSED(this); + if (!(pvt = memget(sizeof *pvt))) { errno = ENOMEM; return (NULL); @@ -174,6 +179,7 @@ irs_lcl_ho(struct irs_acc *this) { ho->minimize = ho_minimize; ho->res_get = ho_res_get; ho->res_set = ho_res_set; + ho->addrinfo = ho_addrinfo; return (ho); } @@ -257,7 +263,7 @@ ho_byaddr(struct irs_ho *this, const void *addr, int len, int af) { (!memcmp(uaddr, mapped, sizeof mapped) || !memcmp(uaddr, tunnelled, sizeof tunnelled))) { /* Unmap. */ - addr = (u_char *)addr + sizeof mapped; + addr = (const u_char *)addr + sizeof mapped; uaddr += sizeof mapped; af = AF_INET; len = INADDRSZ; @@ -479,6 +485,73 @@ ho_res_set(struct irs_ho *this, struct __res_state *res, pvt->free_res = free_res; } +struct lcl_res_target { + struct lcl_res_target *next; + int family; +}; + +/* XXX */ +extern struct addrinfo *hostent2addrinfo __P((struct hostent *, + const struct addrinfo *pai)); + +static struct addrinfo * +ho_addrinfo(struct irs_ho *this, const char *name, const struct addrinfo *pai) +{ + struct pvt *pvt = (struct pvt *)this->private; + struct hostent *hp; + struct lcl_res_target q, q2, *p; + struct addrinfo sentinel, *cur; + + memset(&q, 0, sizeof(q2)); + memset(&q2, 0, sizeof(q2)); + memset(&sentinel, 0, sizeof(sentinel)); + cur = &sentinel; + + switch(pai->ai_family) { + case AF_UNSPEC: /* INET6 then INET4 */ + q.family = AF_INET6; + q.next = &q2; + q2.family = AF_INET; + break; + case AF_INET6: + q.family = AF_INET6; + break; + case AF_INET: + q.family = AF_INET; + break; + default: + RES_SET_H_ERRNO(pvt->res, NO_RECOVERY); /* ??? */ + return(NULL); + } + + for (p = &q; p; p = p->next) { + struct addrinfo *ai; + + hp = (*this->byname2)(this, name, p->family); + if (hp == NULL) { + /* byname2 should've set an appropriate error */ + continue; + } + if ((hp->h_name == NULL) || (hp->h_name[0] == 0) || + (hp->h_addr_list[0] == NULL)) { + RES_SET_H_ERRNO(pvt->res, NO_RECOVERY); + continue; + } + + ai = hostent2addrinfo(hp, pai); + if (ai) { + cur->ai_next = ai; + while (cur && cur->ai_next) + cur = cur->ai_next; + } + } + + if (sentinel.ai_next == NULL) + RES_SET_H_ERRNO(pvt->res, HOST_NOT_FOUND); + + return(sentinel.ai_next); +} + /* Private. */ static size_t diff --git a/contrib/bind/lib/irs/lcl_ng.c b/contrib/bind/lib/irs/lcl_ng.c index 03acbf6..239b63e 100644 --- a/contrib/bind/lib/irs/lcl_ng.c +++ b/contrib/bind/lib/irs/lcl_ng.c @@ -16,7 +16,7 @@ */ #if !defined(LINT) && !defined(CODECENTER) -static const char rcsid[] = "$Id: lcl_ng.c,v 1.16 1999/10/13 16:39:32 vixie Exp $"; +static const char rcsid[] = "$Id: lcl_ng.c,v 1.17 2001/05/29 05:49:05 marka Exp $"; #endif /* Imports */ @@ -39,6 +39,7 @@ static const char rcsid[] = "$Id: lcl_ng.c,v 1.16 1999/10/13 16:39:32 vixie Exp #include "port_after.h" #include "irs_p.h" +#include "lcl_p.h" /* Definitions */ @@ -88,7 +89,8 @@ struct pvt { static void ng_rewind(struct irs_ng *, const char*); static void ng_close(struct irs_ng *); -static int ng_next(struct irs_ng *, char **, char **, char **); +static int ng_next(struct irs_ng *, const char **, + const char **, const char **); static int ng_test(struct irs_ng *, const char *, const char *, const char *, const char *); @@ -104,6 +106,8 @@ struct irs_ng * irs_lcl_ng(struct irs_acc *this) { struct irs_ng *ng; struct pvt *pvt; + + UNUSED(this); if (!(ng = memget(sizeof *ng))) { errno = ENOMEM; @@ -174,7 +178,9 @@ ng_rewind(struct irs_ng *this, const char *group) { * Get the next netgroup off the list. */ static int -ng_next(struct irs_ng *this, char **host, char **user, char **domain) { +ng_next(struct irs_ng *this, const char **host, const char **user, + const char **domain) +{ struct pvt *pvt = (struct pvt *)this->private; if (pvt->nextgrp) { @@ -194,7 +200,7 @@ static int ng_test(struct irs_ng *this, const char *name, const char *host, const char *user, const char *domain) { - char *ng_host, *ng_user, *ng_domain; + const char *ng_host, *ng_user, *ng_domain; ng_rewind(this, name); while (ng_next(this, &ng_host, &ng_user, &ng_domain)) @@ -350,7 +356,7 @@ parse_netgrp(struct irs_ng *this, const char *group) { static struct linelist * read_for_group(struct irs_ng *this, const char *group) { struct pvt *pvt = (struct pvt *)this->private; - char *pos, *spos, *linep, *olinep; + char *pos, *spos, *linep = NULL, *olinep; int len, olen, cont; struct linelist *lp; char line[LINSIZ + 1]; diff --git a/contrib/bind/lib/irs/lcl_nw.c b/contrib/bind/lib/irs/lcl_nw.c index 0d41ec4..457621b 100644 --- a/contrib/bind/lib/irs/lcl_nw.c +++ b/contrib/bind/lib/irs/lcl_nw.c @@ -49,7 +49,7 @@ */ #if defined(LIBC_SCCS) && !defined(lint) -static const char rcsid[] = "$Id: lcl_nw.c,v 1.21 1999/10/15 19:49:10 vixie Exp $"; +static const char rcsid[] = "$Id: lcl_nw.c,v 1.22 2001/05/29 05:49:07 marka Exp $"; /* from getgrent.c 8.2 (Berkeley) 3/21/94"; */ /* from BSDI Id: getgrent.c,v 2.8 1996/05/28 18:15:14 bostic Exp $ */ #endif /* LIBC_SCCS and not lint */ @@ -122,6 +122,8 @@ irs_lcl_nw(struct irs_acc *this) { struct irs_nw *nw; struct pvt *pvt; + UNUSED(this); + if (!(pvt = memget(sizeof *pvt))) { errno = ENOMEM; return (NULL); diff --git a/contrib/bind/lib/irs/lcl_pw.c b/contrib/bind/lib/irs/lcl_pw.c index 2655677..31c1ed0 100644 --- a/contrib/bind/lib/irs/lcl_pw.c +++ b/contrib/bind/lib/irs/lcl_pw.c @@ -49,7 +49,7 @@ */ #if defined(LIBC_SCCS) && !defined(lint) -static const char rcsid[] = "$Id: lcl_pw.c,v 1.19 1999/01/18 07:46:57 vixie Exp $"; +static const char rcsid[] = "$Id: lcl_pw.c,v 1.20 2001/05/29 05:49:08 marka Exp $"; #endif /* LIBC_SCCS and not lint */ /* Extern */ @@ -119,6 +119,8 @@ struct irs_pw * irs_lcl_pw(struct irs_acc *this) { struct irs_pw *pw; struct pvt *pvt; + + UNUSED(this); if (!(pw = memget(sizeof *pw))) { errno = ENOMEM; diff --git a/contrib/bind/lib/irs/lcl_sv.c b/contrib/bind/lib/irs/lcl_sv.c index 7e5bec9..d94366b 100644 --- a/contrib/bind/lib/irs/lcl_sv.c +++ b/contrib/bind/lib/irs/lcl_sv.c @@ -49,7 +49,7 @@ */ #if defined(LIBC_SCCS) && !defined(lint) -static const char rcsid[] = "$Id: lcl_sv.c,v 1.20 1999/10/07 20:44:03 vixie Exp $"; +static const char rcsid[] = "$Id: lcl_sv.c,v 1.22 2001/06/18 14:43:59 marka Exp $"; #endif /* LIBC_SCCS and not lint */ /* extern */ @@ -122,6 +122,8 @@ struct irs_sv * irs_lcl_sv(struct irs_acc *this) { struct irs_sv *sv; struct pvt *pvt; + + UNUSED(this); if ((sv = memget(sizeof *sv)) == NULL) { errno = ENOMEM; @@ -287,13 +289,10 @@ sv_next(struct irs_sv *this) { struct pvt *pvt = (struct pvt *)this->private; #ifdef IRS_LCL_SV_DB - if (pvt->dbh != NULL) - NULL; - else + if (pvt->dbh == NULL && pvt->sv.fp == NULL) +#else + if (pvt->sv.fp == NULL) #endif - if (pvt->sv.fp != NULL) - NULL; - else sv_rewind(this); #ifdef IRS_LCL_SV_DB @@ -395,7 +394,7 @@ sv_db_rec(struct lcl_sv *sv, DBT *key, DBT *data) { return (NULL); sv->serv.s_port = ((u_short *)key->data)[1]; n = strlen(p) + 1; - if (n > sizeof(sv->line)) { + if ((size_t)n > sizeof(sv->line)) { n = sizeof(sv->line); } memcpy(sv->line, p, n); diff --git a/contrib/bind/lib/irs/nis.c b/contrib/bind/lib/irs/nis.c index e19068a..aa10fba 100644 --- a/contrib/bind/lib/irs/nis.c +++ b/contrib/bind/lib/irs/nis.c @@ -16,7 +16,7 @@ */ #if defined(LIBC_SCCS) && !defined(lint) -static const char rcsid[] = "$Id: nis.c,v 1.14 2000/02/28 07:52:16 vixie Exp $"; +static const char rcsid[] = "$Id: nis.c,v 1.15 2001/05/29 05:49:11 marka Exp $"; #endif /* Imports */ @@ -63,6 +63,8 @@ irs_nis_acc(const char *options) { struct irs_acc *acc; char *domain; + UNUSED(options); + if (yp_get_default_domain(&domain) != 0) return (NULL); if (!(nis = memget(sizeof *nis))) { diff --git a/contrib/bind/lib/irs/nis_gr.c b/contrib/bind/lib/irs/nis_gr.c index 713437a..b4e0945 100644 --- a/contrib/bind/lib/irs/nis_gr.c +++ b/contrib/bind/lib/irs/nis_gr.c @@ -49,7 +49,7 @@ */ #if defined(LIBC_SCCS) && !defined(lint) -static const char rcsid[] = "$Id: nis_gr.c,v 1.20 1999/01/30 00:53:16 vixie Exp $"; +static const char rcsid[] = "$Id: nis_gr.c,v 1.21 2001/05/29 05:49:12 marka Exp $"; /* from getgrent.c 8.2 (Berkeley) 3/21/94"; */ /* from BSDI Id: getgrent.c,v 2.8 1996/05/28 18:15:14 bostic Exp $ */ #endif /* LIBC_SCCS and not lint */ @@ -217,7 +217,7 @@ gr_byname(struct irs_gr *this, const char *name) { int r; nisfree(pvt, do_val); - r = yp_match(pvt->nis_domain, group_byname, (char *)name, strlen(name), + r = yp_match(pvt->nis_domain, group_byname, name, strlen(name), &pvt->curval_data, &pvt->curval_len); if (r != 0) { errno = ENOENT; @@ -252,6 +252,7 @@ gr_rewind(struct irs_gr *this) { static void gr_minimize(struct irs_gr *this) { + UNUSED(this); /* NOOP */ } @@ -260,7 +261,7 @@ gr_minimize(struct irs_gr *this) { static struct group * makegroupent(struct irs_gr *this) { struct pvt *pvt = (struct pvt *)this->private; - int num_members = 0; + unsigned int num_members = 0; char *cp, **new; u_long t; diff --git a/contrib/bind/lib/irs/nis_ho.c b/contrib/bind/lib/irs/nis_ho.c index 07d2274..72a8d17 100644 --- a/contrib/bind/lib/irs/nis_ho.c +++ b/contrib/bind/lib/irs/nis_ho.c @@ -16,7 +16,7 @@ */ #if defined(LIBC_SCCS) && !defined(lint) -static const char rcsid[] = "$Id: nis_ho.c,v 1.16 1999/10/13 16:39:32 vixie Exp $"; +static const char rcsid[] = "$Id: nis_ho.c,v 1.18 2001/06/18 14:44:00 marka Exp $"; #endif /* LIBC_SCCS and not lint */ /* Imports */ @@ -103,6 +103,8 @@ static struct __res_state * ho_res_get(struct irs_ho *this); static void ho_res_set(struct irs_ho *this, struct __res_state *res, void (*free_res)(void *)); +static struct addrinfo * ho_addrinfo(struct irs_ho *this, const char *name, + const struct addrinfo *pai); static struct hostent * makehostent(struct irs_ho *this); static void nisfree(struct pvt *, enum do_what); @@ -138,6 +140,7 @@ irs_nis_ho(struct irs_acc *this) { ho->minimize = ho_minimize; ho->res_set = ho_res_set; ho->res_get = ho_res_get; + ho->addrinfo = ho_addrinfo; return (ho); } @@ -175,13 +178,17 @@ static struct hostent * ho_byname2(struct irs_ho *this, const char *name, int af) { struct pvt *pvt = (struct pvt *)this->private; int r; + char *tmp; + + UNUSED(af); if (init(this) == -1) return (NULL); nisfree(pvt, do_val); - r = yp_match(pvt->nis_domain, hosts_byname, (char *)name, strlen(name), - &pvt->curval_data, &pvt->curval_len); + DE_CONST(name, tmp); + r = yp_match(pvt->nis_domain, hosts_byname, tmp, + strlen(tmp), &pvt->curval_data, &pvt->curval_len); if (r != 0) { RES_SET_H_ERRNO(pvt->res, HOST_NOT_FOUND); return (NULL); @@ -203,7 +210,7 @@ ho_byaddr(struct irs_ho *this, const void *addr, int len, int af) { (!memcmp(uaddr, mapped, sizeof mapped) || !memcmp(uaddr, tunnelled, sizeof tunnelled))) { /* Unmap. */ - addr = (u_char *)addr + sizeof mapped; + addr = (const u_char *)addr + sizeof mapped; uaddr += sizeof mapped; af = AF_INET; len = INADDRSZ; @@ -307,6 +314,72 @@ ho_res_set(struct irs_ho *this, struct __res_state *res, pvt->free_res = free_res; } +struct nis_res_target { + struct nis_res_target *next; + int family; +}; + +/* XXX */ +extern struct addrinfo *hostent2addrinfo __P((struct hostent *, + const struct addrinfo *pai)); + +static struct addrinfo * +ho_addrinfo(struct irs_ho *this, const char *name, const struct addrinfo *pai) +{ + struct pvt *pvt = (struct pvt *)this->private; + struct hostent *hp; + struct nis_res_target q, q2, *p; + struct addrinfo sentinel, *cur; + + memset(&q, 0, sizeof(q2)); + memset(&q2, 0, sizeof(q2)); + memset(&sentinel, 0, sizeof(sentinel)); + cur = &sentinel; + + switch(pai->ai_family) { + case AF_UNSPEC: /* INET6 then INET4 */ + q.family = AF_INET6; + q.next = &q2; + q2.family = AF_INET; + break; + case AF_INET6: + q.family = AF_INET6; + break; + case AF_INET: + q.family = AF_INET; + break; + default: + RES_SET_H_ERRNO(pvt->res, NO_RECOVERY); /* ??? */ + return(NULL); + } + + for (p = &q; p; p = p->next) { + struct addrinfo *ai; + + hp = (*this->byname2)(this, name, p->family); + if (hp == NULL) { + /* byname2 should've set an appropriate error */ + continue; + } + if ((hp->h_name == NULL) || (hp->h_name[0] == 0) || + (hp->h_addr_list[0] == NULL)) { + RES_SET_H_ERRNO(pvt->res, NO_RECOVERY); + continue; + } + ai = hostent2addrinfo(hp, pai); + if (ai) { + cur->ai_next = ai; + while (cur && cur->ai_next) + cur = cur->ai_next; + } + } + + if (sentinel.ai_next == NULL) + RES_SET_H_ERRNO(pvt->res, HOST_NOT_FOUND); + + return(sentinel.ai_next); +} + /* Private */ static struct hostent * diff --git a/contrib/bind/lib/irs/nis_ng.c b/contrib/bind/lib/irs/nis_ng.c index 88d97ff..a42d994 100644 --- a/contrib/bind/lib/irs/nis_ng.c +++ b/contrib/bind/lib/irs/nis_ng.c @@ -16,7 +16,7 @@ */ #if defined(LIBC_SCCS) && !defined(lint) -static const char rcsid[] = "$Id: nis_ng.c,v 1.16 1999/01/18 07:46:58 vixie Exp $"; +static const char rcsid[] = "$Id: nis_ng.c,v 1.17 2001/05/29 05:49:14 marka Exp $"; #endif /* Imports */ @@ -78,7 +78,8 @@ static /*const*/ char netgroup_map[] = "netgroup"; /* Forward */ static void ng_close(struct irs_ng *); -static int ng_next(struct irs_ng *, char **, char **, char **); +static int ng_next(struct irs_ng *, const char **, + const char **, const char **); static int ng_test(struct irs_ng *, const char *, const char *, const char *, const char *); @@ -129,14 +130,14 @@ ng_close(struct irs_ng *this) { } static int -ng_next(struct irs_ng *this, char **host, char **user, char **domain) { +ng_next(struct irs_ng *this, const char **host, const char **user, const char **domain) { struct pvt *pvt = (struct pvt *)this->private; if (!pvt->cur) return (0); - *host = (/*const*/ char *)pvt->cur->host; - *user = (/*const*/ char *)pvt->cur->user; - *domain = (/*const*/ char *)pvt->cur->domain; + *host = pvt->cur->host; + *user = pvt->cur->user; + *domain = pvt->cur->domain; pvt->cur = pvt->cur->next; return (1); } @@ -178,6 +179,7 @@ ng_rewind(struct irs_ng *this, const char *name) { static void ng_minimize(struct irs_ng *this) { + UNUSED(this); /* NOOP */ } @@ -188,13 +190,15 @@ add_group_to_list(struct pvt *pvt, const char *name, int len) { char *vdata, *cp, *np; struct tmpgrp *tmp; int vlen, r; + char *nametmp; /* Don't add the same group to the list more than once. */ for (tmp = pvt->tmp; tmp; tmp = tmp->next) if (!strcmp(tmp->name, name)) return; - r = yp_match(pvt->nis_domain, netgroup_map, (char *)name, len, + DE_CONST(name, nametmp); + r = yp_match(pvt->nis_domain, netgroup_map, nametmp, len, &vdata, &vlen); if (r == 0) { cp = vdata; diff --git a/contrib/bind/lib/irs/nis_nw.c b/contrib/bind/lib/irs/nis_nw.c index 72ec391..bc659f3 100644 --- a/contrib/bind/lib/irs/nis_nw.c +++ b/contrib/bind/lib/irs/nis_nw.c @@ -16,7 +16,7 @@ */ #if defined(LIBC_SCCS) && !defined(lint) -static const char rcsid[] = "$Id: nis_nw.c,v 1.15 1999/01/18 07:46:58 vixie Exp $"; +static const char rcsid[] = "$Id: nis_nw.c,v 1.16 2001/05/29 05:49:15 marka Exp $"; #endif /* LIBC_SCCS and not lint */ /* Imports */ @@ -187,6 +187,7 @@ static struct nwent * nw_byname(struct irs_nw *this, const char *name, int af) { struct pvt *pvt = (struct pvt *)this->private; int r; + char *tmp; if (init(this) == -1) return (NULL); @@ -197,8 +198,9 @@ nw_byname(struct irs_nw *this, const char *name, int af) { return (NULL); } nisfree(pvt, do_val); - r = yp_match(pvt->nis_domain, networks_byname, (char *)name, - strlen(name), &pvt->curval_data, &pvt->curval_len); + DE_CONST(name, tmp); + r = yp_match(pvt->nis_domain, networks_byname, tmp, + strlen(tmp), &pvt->curval_data, &pvt->curval_len); if (r != 0) { RES_SET_H_ERRNO(pvt->res, HOST_NOT_FOUND); return (NULL); diff --git a/contrib/bind/lib/irs/nis_pr.c b/contrib/bind/lib/irs/nis_pr.c index 8dff084..bc09075 100644 --- a/contrib/bind/lib/irs/nis_pr.c +++ b/contrib/bind/lib/irs/nis_pr.c @@ -16,7 +16,7 @@ */ #if defined(LIBC_SCCS) && !defined(lint) -static const char rcsid[] = "$Id: nis_pr.c,v 1.13 1999/01/18 07:46:59 vixie Exp $"; +static const char rcsid[] = "$Id: nis_pr.c,v 1.14 2001/05/29 05:49:16 marka Exp $"; #endif /* Imports */ @@ -132,10 +132,12 @@ static struct protoent * pr_byname(struct irs_pr *this, const char *name) { struct pvt *pvt = (struct pvt *)this->private; int r; + char *tmp; nisfree(pvt, do_val); - r = yp_match(pvt->nis_domain, protocols_byname, (char *)name, - strlen(name), &pvt->curval_data, &pvt->curval_len); + DE_CONST(name, tmp); + r = yp_match(pvt->nis_domain, protocols_byname, tmp, + strlen(tmp), &pvt->curval_data, &pvt->curval_len); if (r != 0) { errno = ENOENT; return (NULL); @@ -204,6 +206,7 @@ pr_rewind(struct irs_pr *this) { static void pr_minimize(struct irs_pr *this) { + UNUSED(this); /* NOOP */ } @@ -220,9 +223,9 @@ makeprotoent(struct irs_pr *this) { pvt->prbuf = pvt->curval_data; pvt->curval_data = NULL; - for (p = pvt->prbuf; *p && *p != '#'; p++) - NULL; - while (p > pvt->prbuf && isspace(p[-1])) + for (p = pvt->prbuf; *p && *p != '#';) + p++; + while (p > pvt->prbuf && isspace((unsigned char)(p[-1]))) p--; *p = '\0'; @@ -230,16 +233,16 @@ makeprotoent(struct irs_pr *this) { n = m = 0; pvt->proto.p_name = p; - while (*p && !isspace(*p)) + while (*p && !isspace((unsigned char)*p)) p++; if (!*p) return (NULL); *p++ = '\0'; - while (*p && isspace(*p)) + while (*p && isspace((unsigned char)*p)) p++; pvt->proto.p_proto = atoi(p); - while (*p && !isspace(*p)) + while (*p && !isspace((unsigned char)*p)) p++; *p++ = '\0'; @@ -255,7 +258,7 @@ makeprotoent(struct irs_pr *this) { pvt->proto.p_aliases = t; } pvt->proto.p_aliases[n++] = p; - while (*p && !isspace(*p)) + while (*p && !isspace((unsigned char)*p)) p++; if (*p) *p++ = '\0'; diff --git a/contrib/bind/lib/irs/nis_pw.c b/contrib/bind/lib/irs/nis_pw.c index ce90f20..1d345a5 100644 --- a/contrib/bind/lib/irs/nis_pw.c +++ b/contrib/bind/lib/irs/nis_pw.c @@ -16,7 +16,7 @@ */ #if defined(LIBC_SCCS) && !defined(lint) -static const char rcsid[] = "$Id: nis_pw.c,v 1.16 1999/01/30 00:53:16 vixie Exp $"; +static const char rcsid[] = "$Id: nis_pw.c,v 1.17 2001/05/29 05:49:18 marka Exp $"; #endif /* LIBC_SCCS and not lint */ /* Imports */ @@ -169,9 +169,11 @@ static struct passwd * pw_byname(struct irs_pw *this, const char *name) { struct pvt *pvt = (struct pvt *)this->private; int r; + char *tmp; nisfree(pvt, do_val); - r = yp_match(pvt->nis_domain, passwd_byname, name, strlen(name), + DE_CONST(name, tmp); + r = yp_match(pvt->nis_domain, passwd_byname, tmp, strlen(tmp), &pvt->curval_data, &pvt->curval_len); if (r != 0) { errno = ENOENT; @@ -206,6 +208,7 @@ pw_rewind(struct irs_pw *this) { static void pw_minimize(struct irs_pw *this) { + UNUSED(this); /* NOOP */ } @@ -226,7 +229,9 @@ makepasswdent(struct irs_pw *this) { pvt->passwd.pw_name = cp; if (!(cp = strchr(cp, ':'))) goto cleanup; +#ifdef HAS_PW_CLASS pvt->passwd.pw_class = cp; /* Needs to point at a \0. */ +#endif *cp++ = '\0'; pvt->passwd.pw_passwd = cp; diff --git a/contrib/bind/lib/irs/nis_sv.c b/contrib/bind/lib/irs/nis_sv.c index 8810fd2..40bfda5 100644 --- a/contrib/bind/lib/irs/nis_sv.c +++ b/contrib/bind/lib/irs/nis_sv.c @@ -16,7 +16,7 @@ */ #if defined(LIBC_SCCS) && !defined(lint) -static const char rcsid[] = "$Id: nis_sv.c,v 1.14 1999/01/18 07:46:59 vixie Exp $"; +static const char rcsid[] = "$Id: nis_sv.c,v 1.15 2001/05/29 05:49:19 marka Exp $"; #endif /* LIBC_SCCS and not lint */ /* Imports */ @@ -205,6 +205,7 @@ sv_next(struct irs_sv *this) { static void sv_minimize(struct irs_sv *this) { + UNUSED(this); /* NOOP */ } @@ -242,7 +243,7 @@ makeservent(struct irs_sv *this) { pvt->serv.s_port = htons((u_short) atoi(p)); pvt->serv.s_proto = NULL; - while (*p && !isspace(*p)) + while (*p && !isspace((unsigned char)*p)) if (*p++ == '/') pvt->serv.s_proto = p; if (!pvt->serv.s_proto) diff --git a/contrib/bind/lib/irs/nul_ng.c b/contrib/bind/lib/irs/nul_ng.c index cc5c801..1a61d8c 100644 --- a/contrib/bind/lib/irs/nul_ng.c +++ b/contrib/bind/lib/irs/nul_ng.c @@ -16,7 +16,7 @@ */ #if defined(LIBC_SCCS) && !defined(lint) -static const char rcsid[] = "$Id: nul_ng.c,v 1.10 1999/01/18 07:46:59 vixie Exp $"; +static const char rcsid[] = "$Id: nul_ng.c,v 1.11 2001/05/29 05:49:20 marka Exp $"; #endif /* @@ -49,7 +49,8 @@ static const char rcsid[] = "$Id: nul_ng.c,v 1.10 1999/01/18 07:46:59 vixie Exp /* Forward. */ static void ng_close(struct irs_ng *); -static int ng_next(struct irs_ng *, char **, char **, char **); +static int ng_next(struct irs_ng *, const char **, + const char **, const char **); static int ng_test(struct irs_ng *, const char *, const char *, const char *, const char *); @@ -62,6 +63,8 @@ struct irs_ng * irs_nul_ng(struct irs_acc *this) { struct irs_ng *ng; + UNUSED(this); + if (!(ng = memget(sizeof *ng))) { errno = ENOMEM; return (NULL); @@ -85,7 +88,13 @@ ng_close(struct irs_ng *this) { /* ARGSUSED */ static int -ng_next(struct irs_ng *this, char **host, char **user, char **domain) { +ng_next(struct irs_ng *this, const char **host, const char **user, + const char **domain) +{ + UNUSED(this); + UNUSED(host); + UNUSED(user); + UNUSED(domain); errno = ENOENT; return (-1); } @@ -94,16 +103,24 @@ static int ng_test(struct irs_ng *this, const char *name, const char *user, const char *host, const char *domain) { + UNUSED(this); + UNUSED(name); + UNUSED(user); + UNUSED(host); + UNUSED(domain); errno = ENODEV; return (-1); } static void ng_rewind(struct irs_ng *this, const char *netgroup) { + UNUSED(this); + UNUSED(netgroup); /* NOOP */ } static void ng_minimize(struct irs_ng *this) { + UNUSED(this); /* NOOP */ } diff --git a/contrib/bind/lib/irs/util.c b/contrib/bind/lib/irs/util.c index 1d097c6..e37f4d9 100644 --- a/contrib/bind/lib/irs/util.c +++ b/contrib/bind/lib/irs/util.c @@ -16,7 +16,7 @@ */ #if defined(LIBC_SCCS) && !defined(lint) -static const char rcsid[] = "$Id: util.c,v 1.11 2000/02/04 08:28:33 vixie Exp $"; +static const char rcsid[] = "$Id: util.c,v 1.12 2001/05/29 05:49:21 marka Exp $"; #endif #include "port_before.h" @@ -89,7 +89,7 @@ make_group_list(struct irs_gr *this, const char *name, */ (*this->rewind)(this); while ((grp = (*this->next)(this)) != NULL) { - if (grp->gr_gid == basegid) + if ((gid_t)grp->gr_gid == basegid) continue; for (i = 0; grp->gr_mem[i]; i++) { if (!strcmp(grp->gr_mem[i], name)) { diff --git a/contrib/bind/lib/isc/Makefile b/contrib/bind/lib/isc/Makefile index 7845365..0127c6d 100644 --- a/contrib/bind/lib/isc/Makefile +++ b/contrib/bind/lib/isc/Makefile @@ -13,7 +13,7 @@ # ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS # SOFTWARE. -# $Id: Makefile,v 8.28 2000/12/23 08:03:00 vixie Exp $ +# $Id: Makefile,v 8.30 2001/08/14 05:58:08 marka Exp $ # these are only appropriate for BSD 4.4 or derivatives, and are used in # development. normal builds will be done in the top level directory and @@ -48,14 +48,14 @@ SRCS= tree.c base64.c bitncmp.c assertions.c \ ctl_p.c ctl_srvr.c ctl_clnt.c \ eventlib.c ev_connects.c ev_files.c \ ev_timers.c ev_streams.c ev_waits.c \ - movefile.c + hex.c movefile.c OBJS= tree.${O} base64.${O} bitncmp.${O} assertions.${O} \ memcluster.${O} logging.${O} heap.${O} \ ctl_p.${O} ctl_srvr.${O} ctl_clnt.${O} \ eventlib.${O} ev_connects.${O} ev_files.${O} \ ev_timers.${O} ev_streams.${O} ev_waits.${O} \ - movefile.${O} + hex.${O} movefile.${O} all: ${LIBBIND} @@ -67,7 +67,7 @@ ${LIBBIND}: ${OBJS} ${RANLIB} ${LIBBIND} .c.${O}: - if test ! -d ${THREADED} ; then mkdir ${THREADED} ; else true ; fi + mkdir ${THREADED} 2> /dev/null || test -d ${THREADED} -a -w ${THREADED} ${CC} ${CPPFLAGS} ${CFLAGS} ${BOUNDS} ${REENTRANT} -c $*.c \ -o ${THREADED}/$*.${O} -${LDS} ${LD} ${LD_LIBFLAGS} ${THREADED}/$*.${O} \ diff --git a/contrib/bind/lib/isc/assertions.c b/contrib/bind/lib/isc/assertions.c index b53cc0a..704801c 100644 --- a/contrib/bind/lib/isc/assertions.c +++ b/contrib/bind/lib/isc/assertions.c @@ -16,7 +16,7 @@ */ #if !defined(LINT) && !defined(CODECENTER) -static const char rcsid[] = "$Id: assertions.c,v 8.3 1999/01/08 19:25:14 vixie Exp $"; +static const char rcsid[] = "$Id: assertions.c,v 8.4 2001/05/29 05:49:22 marka Exp $"; #endif #include "port_before.h" @@ -34,7 +34,8 @@ static const char rcsid[] = "$Id: assertions.c,v 8.3 1999/01/08 19:25:14 vixie E * Forward. */ -static void default_assertion_failed(char *, int, assertion_type, char *, int); +static void default_assertion_failed(const char *, int, assertion_type, + const char *, int); /* * Public. @@ -50,9 +51,9 @@ set_assertion_failure_callback(assertion_failure_callback f) { __assertion_failed = f; } -char * +const char * assertion_type_to_text(assertion_type type) { - char *result; + const char *result; switch (type) { case assert_require: @@ -78,8 +79,8 @@ assertion_type_to_text(assertion_type type) { */ static void -default_assertion_failed(char *file, int line, assertion_type type, char *cond, - int print_errno) +default_assertion_failed(const char *file, int line, assertion_type type, + const char *cond, int print_errno) { fprintf(stderr, "%s:%d: %s(%s)%s%s failed.\n", file, line, assertion_type_to_text(type), cond, diff --git a/contrib/bind/lib/isc/assertions.mdoc b/contrib/bind/lib/isc/assertions.mdoc index 3d8d103..863829a 100644 --- a/contrib/bind/lib/isc/assertions.mdoc +++ b/contrib/bind/lib/isc/assertions.mdoc @@ -1,4 +1,4 @@ -.\" $Id: assertions.mdoc,v 8.2 1999/01/08 19:25:15 vixie Exp $ +.\" $Id: assertions.mdoc,v 8.3 2001/08/08 07:50:20 marka Exp $ .\" .\"Copyright (c) 1997,1999 by Internet Software Consortium. .\" @@ -75,9 +75,9 @@ macro. If this macro's value is when .Dq "<isc/assertions.h>" is included, then assertions of that type will not be checked. E.g. - +.Pp .Dl #define CHECK_ENSURE 0 - +.Pp will disable checking of .Fn ENSURE and @@ -93,8 +93,7 @@ assertion types should be checked. specifies the function to call when an assertion fails. .Pp When an -.li -assertion_failure_callback +.Fn assertion_failure_callback is called, the .Fa filename and @@ -109,7 +108,7 @@ assert_ensure assert_insist assert_invariant .Ed - +.Pp and may be used by the callback to determine the type of the failing assertion. .Fa condition @@ -127,8 +126,13 @@ For example, returns the string .Dq REQUIRE . .Sh SEE ALSO -Bertrand Meyer, -.Sy Object-Oriented Software Construction, -2nd edition, Prentice\-Hall, 1997, ISBN 0\-13\-629155\-4, chapter 11. +.Rs +.%A Bertrand Meyer +.%B Object-Oriented Software Construction, 2nd edition +.%Q Prentice\-Hall +.%D 1997 +.%O ISBN 0\-13\-629155\-4 +.%P chapter 11 +.Re .Sh AUTHOR Bob Halley (ISC). diff --git a/contrib/bind/lib/isc/bitncmp.c b/contrib/bind/lib/isc/bitncmp.c index 8dadca0..c86db62 100644 --- a/contrib/bind/lib/isc/bitncmp.c +++ b/contrib/bind/lib/isc/bitncmp.c @@ -16,7 +16,7 @@ */ #if defined(LIBC_SCCS) && !defined(lint) -static const char rcsid[] = "$Id: bitncmp.c,v 1.6 1999/01/08 19:25:20 vixie Exp $"; +static const char rcsid[] = "$Id: bitncmp.c,v 1.7 2001/05/29 05:49:23 marka Exp $"; #endif #include "port_before.h" @@ -51,8 +51,8 @@ bitncmp(const void *l, const void *r, int n) { if (x) return (x); - lb = ((u_char *)l)[b]; - rb = ((u_char *)r)[b]; + lb = ((const u_char *)l)[b]; + rb = ((const u_char *)r)[b]; for (b = n % 8; b > 0; b--) { if ((lb & 0x80) != (rb & 0x80)) { if (lb & 0x80) diff --git a/contrib/bind/lib/isc/bitncmp.mdoc b/contrib/bind/lib/isc/bitncmp.mdoc index 4fa12e8..d3cff2e 100644 --- a/contrib/bind/lib/isc/bitncmp.mdoc +++ b/contrib/bind/lib/isc/bitncmp.mdoc @@ -1,4 +1,4 @@ -.\" $Id: bitncmp.mdoc,v 8.2 1999/01/08 19:25:21 vixie Exp $ +.\" $Id: bitncmp.mdoc,v 8.3 2001/08/08 07:50:21 marka Exp $ .\" .\"Copyright (c) 1996,1999 by Internet Software Consortium. .\" @@ -41,7 +41,7 @@ is lexicographically less than, equal to, or greater than when taken to be unsigned characters (this behaviour is just like that of .Xr memcmp 3 ) . .Pp -.Sy NOTE: +.Sy NOTE : .Fn Bitncmp assumes .Sy network byte order ; @@ -52,7 +52,7 @@ this means that the fourth octet of .Fn Bitncmp returns values in the manner of .Xr memcmp 3 : -.Bd -filled -offset indent +.Bd -ragged -offset indent +1 if .Dq Fa 1 is greater than @@ -75,7 +75,7 @@ where and .Dq Fa r are both interpreted as strings of unsigned characters (through bit -.Dq Fa n .) +.Dq Fa n . ) .Sh SEE ALSO .Xr memcmp 3 . .Sh AUTHOR diff --git a/contrib/bind/lib/isc/ctl_clnt.c b/contrib/bind/lib/isc/ctl_clnt.c index 4e19d2c..56e5098 100644 --- a/contrib/bind/lib/isc/ctl_clnt.c +++ b/contrib/bind/lib/isc/ctl_clnt.c @@ -1,5 +1,5 @@ #if !defined(lint) && !defined(SABER) -static const char rcsid[] = "$Id: ctl_clnt.c,v 8.15 2000/11/14 01:10:36 vixie Exp $"; +static const char rcsid[] = "$Id: ctl_clnt.c,v 8.17 2001/06/06 00:33:35 marka Exp $"; #endif /* not lint */ /* @@ -55,8 +55,9 @@ static const char rcsid[] = "$Id: ctl_clnt.c,v 8.15 2000/11/14 01:10:36 vixie Ex /* Macros. */ #define donefunc_p(ctx) ((ctx).donefunc != NULL) -#define arpacode_p(line) (isdigit(line[0]) && isdigit(line[1]) && \ - isdigit(line[2])) +#define arpacode_p(line) (isdigit((unsigned char)(line[0])) && \ + isdigit((unsigned char)(line[1])) && \ + isdigit((unsigned char)(line[2]))) #define arpacont_p(line) (line[3] == '-') #define arpadone_p(line) (line[3] == ' ' || line[3] == '\t' || \ line[3] == '\r' || line[3] == '\0') @@ -135,6 +136,7 @@ ctl_client(evContext lev, const struct sockaddr *cap, size_t cap_len, static const char me[] = "ctl_client"; static const int on = 1; struct ctl_cctx *ctx; + struct sockaddr *captmp; if (logger == NULL) logger = ctl_logger; @@ -168,18 +170,19 @@ ctl_client(evContext lev, const struct sockaddr *cap, size_t cap_len, } if (cap != NULL) { if (setsockopt(ctx->sock, SOL_SOCKET, SO_REUSEADDR, - (char *)&on, sizeof on) != 0) { + (const char *)&on, sizeof on) != 0) { (*ctx->logger)(ctl_warning, "%s: setsockopt(REUSEADDR): %s", me, strerror(errno)); } - if (bind(ctx->sock, cap, cap_len) < 0) { + DE_CONST(cap, captmp); + if (bind(ctx->sock, captmp, cap_len) < 0) { (*ctx->logger)(ctl_error, "%s: bind: %s", me, strerror(errno)); goto fatal; } } - if (evConnect(lev, ctx->sock, (struct sockaddr *)sap, sap_len, + if (evConnect(lev, ctx->sock, (const struct sockaddr *)sap, sap_len, conn_done, ctx, &ctx->coID) < 0) { (*ctx->logger)(ctl_error, "%s: evConnect(fd %d): %s", me, (void *)ctx->sock, strerror(errno)); @@ -219,7 +222,7 @@ ctl_command(struct ctl_cctx *ctx, const char *cmd, size_t len, { struct ctl_tran *tran; char *pc; - int n; + unsigned int n; switch (ctx->state) { case destroyed: @@ -243,7 +246,8 @@ ctl_command(struct ctl_cctx *ctx, const char *cmd, size_t len, memcpy(tran->outbuf.text, cmd, len); tran->outbuf.used = len; for (pc = tran->outbuf.text, n = 0; n < tran->outbuf.used; pc++, n++) - if (!isascii(*pc) || !isprint(*pc)) + if (!isascii((unsigned char)*pc) || + !isprint((unsigned char)*pc)) *pc = '\040'; start_write(ctx); return (0); @@ -274,6 +278,7 @@ start_write(struct ctl_cctx *ctx) { static const char me[] = "isc/ctl_clnt::start_write"; struct ctl_tran *tran; struct iovec iov[2], *iovp = iov; + char * tmp; REQUIRE(ctx->state == connecting || ctx->state == connected); /* If there is a write in progress, don't try to write more yet. */ @@ -297,7 +302,8 @@ start_write(struct ctl_cctx *ctx) { return; /* Marshall a newline-terminated message and clock it out. */ *iovp++ = evConsIovec(tran->outbuf.text, tran->outbuf.used); - *iovp++ = evConsIovec("\r\n", 2); + DE_CONST("\r\n", tmp); + *iovp++ = evConsIovec(tmp, 2); if (evWrite(ctx->ev, ctx->sock, iov, iovp - iov, write_done, tran, &ctx->wrID) < 0) { (*ctx->logger)(ctl_error, "%s: evWrite: %s", me, @@ -387,6 +393,12 @@ conn_done(evContext ev, void *uap, int fd, struct ctl_cctx *ctx = uap; struct ctl_tran *tran; + UNUSED(ev); + UNUSED(la); + UNUSED(lalen); + UNUSED(ra); + UNUSED(ralen); + ctx->coID.opaque = NULL; if (fd < 0) { (*ctx->logger)(ctl_error, "%s: evConnect: %s", me, @@ -416,6 +428,9 @@ write_done(evContext lev, void *uap, int fd, int bytes) { struct ctl_tran *tran = (struct ctl_tran *)uap; struct ctl_cctx *ctx = tran->ctx; + UNUSED(lev); + UNUSED(fd); + ctx->wrID.opaque = NULL; if (ctx->tiID.opaque != NULL) touch_timer(ctx); @@ -459,6 +474,8 @@ readable(evContext ev, void *uap, int fd, int evmask) { ssize_t n; char *eos; + UNUSED(ev); + REQUIRE(ctx != NULL); REQUIRE(fd >= 0); REQUIRE(evmask == EV_READ); @@ -574,6 +591,10 @@ timer(evContext ev, void *uap, struct timespec due, struct timespec itv) { static const char me[] = "isc/ctl_clnt::timer"; struct ctl_cctx *ctx = uap; + UNUSED(ev); + UNUSED(due); + UNUSED(itv); + ctx->tiID.opaque = NULL; (*ctx->logger)(ctl_error, "%s: timeout after %u seconds while %s", me, ctx->timeout.tv_sec, state_names[ctx->state]); diff --git a/contrib/bind/lib/isc/ctl_p.c b/contrib/bind/lib/isc/ctl_p.c index 7d9058c..4f22f9f 100644 --- a/contrib/bind/lib/isc/ctl_p.c +++ b/contrib/bind/lib/isc/ctl_p.c @@ -1,5 +1,5 @@ #if !defined(lint) && !defined(SABER) -static const char rcsid[] = "$Id: ctl_p.c,v 8.7 2000/02/04 08:28:33 vixie Exp $"; +static const char rcsid[] = "$Id: ctl_p.c,v 8.8 2001/05/29 05:49:26 marka Exp $"; #endif /* not lint */ /* @@ -104,11 +104,30 @@ ctl_sa_ntop(const struct sockaddr *sa, { static const char me[] = "ctl_sa_ntop"; static const char punt[] = "[0].-1"; - char tmp[sizeof "255.255.255.255"]; + char tmp[INET6_ADDRSTRLEN]; switch (sa->sa_family) { + case AF_INET6: { + const struct sockaddr_in6 *in6 = + (const struct sockaddr_in6 *) sa; + + if (inet_ntop(in6->sin6_family, &in6->sin6_addr, tmp, sizeof tmp) + == NULL) { + (*logger)(ctl_error, "%s: inet_ntop(%u %04x): %s", + me, in6->sin6_family, + in6->sin6_port, strerror(errno)); + return (punt); + } + if (strlen(tmp) + sizeof "[].65535" > size) { + (*logger)(ctl_error, "%s: buffer overflow", me); + return (punt); + } + (void) sprintf(buf, "[%s].%u", tmp, ntohs(in6->sin6_port)); + return (buf); + } case AF_INET: { - const struct sockaddr_in *in = (struct sockaddr_in *) sa; + const struct sockaddr_in *in = + (const struct sockaddr_in *) sa; if (inet_ntop(in->sin_family, &in->sin_addr, tmp, sizeof tmp) == NULL) { @@ -127,8 +146,9 @@ ctl_sa_ntop(const struct sockaddr *sa, } #ifndef NO_SOCKADDR_UN case AF_UNIX: { - const struct sockaddr_un *un = (struct sockaddr_un *) sa; - int x = sizeof un->sun_path; + const struct sockaddr_un *un = + (const struct sockaddr_un *) sa; + unsigned int x = sizeof un->sun_path; if (x > size) x = size; @@ -145,12 +165,18 @@ ctl_sa_ntop(const struct sockaddr *sa, void ctl_sa_copy(const struct sockaddr *src, struct sockaddr *dst) { switch (src->sa_family) { + case AF_INET6: + *((struct sockaddr_in6 *)dst) = + *((const struct sockaddr_in6 *)src); + break; case AF_INET: - *((struct sockaddr_in *)dst) = *((struct sockaddr_in *)src); + *((struct sockaddr_in *)dst) = + *((const struct sockaddr_in *)src); break; #ifndef NO_SOCKADDR_UN case AF_UNIX: - *((struct sockaddr_un *)dst) = *((struct sockaddr_un *)src); + *((struct sockaddr_un *)dst) = + *((const struct sockaddr_un *)src); break; #endif default: diff --git a/contrib/bind/lib/isc/ctl_p.h b/contrib/bind/lib/isc/ctl_p.h index 1ebb254..42aade7 100644 --- a/contrib/bind/lib/isc/ctl_p.h +++ b/contrib/bind/lib/isc/ctl_p.h @@ -4,7 +4,11 @@ struct ctl_buf { }; #define MAX_LINELEN 990 /* Like SMTP. */ +#ifndef NO_SOCKADDR_UN +#define MAX_NTOP PATH_MAX +#else #define MAX_NTOP (sizeof "[255.255.255.255].65535") +#endif #define allocated_p(Buf) ((Buf).text != NULL) #define buffer_init(Buf) ((Buf).text = 0, (Buf.used) = 0) diff --git a/contrib/bind/lib/isc/ctl_srvr.c b/contrib/bind/lib/isc/ctl_srvr.c index 9beea0d..91a2c1b 100644 --- a/contrib/bind/lib/isc/ctl_srvr.c +++ b/contrib/bind/lib/isc/ctl_srvr.c @@ -1,5 +1,5 @@ #if !defined(lint) && !defined(SABER) -static const char rcsid[] = "$Id: ctl_srvr.c,v 8.24 2000/11/14 01:10:37 vixie Exp $"; +static const char rcsid[] = "$Id: ctl_srvr.c,v 8.25 2001/05/29 05:49:27 marka Exp $"; #endif /* not lint */ /* @@ -92,7 +92,7 @@ struct ctl_sess { struct ctl_buf outbuf; const struct ctl_verb * verb; u_int helpcode; - void * respctx; + const void * respctx; u_int respflags; ctl_srvrdone donefunc; void * uap; @@ -139,7 +139,7 @@ static void ctl_morehelp(struct ctl_sctx *, struct ctl_sess *, const struct ctl_verb *, const char *, - u_int, void *, void *); + u_int, const void *, void *); static void ctl_signal_done(struct ctl_sctx *, struct ctl_sess *); @@ -152,7 +152,9 @@ static const char * state_names[] = { static const char space[] = " "; -static const struct ctl_verb fakehelpverb = { "fakehelp", ctl_morehelp }; +static const struct ctl_verb fakehelpverb = { + "fakehelp", ctl_morehelp , NULL +}; /* Public. */ @@ -225,7 +227,7 @@ ctl_server(evContext lev, const struct sockaddr *sap, size_t sap_len, if (sap->sa_family != AF_UNIX) #endif if (setsockopt(ctx->sock, SOL_SOCKET, SO_REUSEADDR, - (char *)&on, sizeof on) != 0) { + (const char *)&on, sizeof on) != 0) { (*ctx->logger)(ctl_warning, "%s: setsockopt(REUSEADDR): %s", me, strerror(errno)); @@ -234,7 +236,7 @@ ctl_server(evContext lev, const struct sockaddr *sap, size_t sap_len, char tmp[MAX_NTOP]; save_errno = errno; (*ctx->logger)(ctl_error, "%s: bind: %s: %s", - me, ctl_sa_ntop((struct sockaddr *)sap, + me, ctl_sa_ntop((const struct sockaddr *)sap, tmp, sizeof tmp, ctx->logger), strerror(save_errno)); close(ctx->sock); @@ -295,8 +297,8 @@ ctl_endserver(struct ctl_sctx *ctx) { */ void ctl_response(struct ctl_sess *sess, u_int code, const char *text, - u_int flags, void *respctx, ctl_srvrdone donefunc, void *uap, - const char *body, size_t bodylen) + u_int flags, const void *respctx, ctl_srvrdone donefunc, + void *uap, const char *body, size_t bodylen) { static const char me[] = "ctl_response"; struct iovec iov[3], *iovp = iov; @@ -327,13 +329,18 @@ ctl_response(struct ctl_sess *sess, u_int code, const char *text, sess->outbuf.used = SPRINTF((sess->outbuf.text, "%03d%c%s\r\n", code, (flags & CTL_MORE) != 0 ? '-' : ' ', text)); - for (pc = sess->outbuf.text, n = 0; n < sess->outbuf.used-2; pc++, n++) - if (!isascii(*pc) || !isprint(*pc)) + for (pc = sess->outbuf.text, n = 0; + n < (int)sess->outbuf.used-2; pc++, n++) + if (!isascii((unsigned char)*pc) || + !isprint((unsigned char)*pc)) *pc = '\040'; *iovp++ = evConsIovec(sess->outbuf.text, sess->outbuf.used); if (body != NULL) { - *iovp++ = evConsIovec((char *)body, bodylen); - *iovp++ = evConsIovec(".\r\n", 3); + char *tmp; + DE_CONST(body, tmp); + *iovp++ = evConsIovec(tmp, bodylen); + DE_CONST(".\r\n", tmp); + *iovp++ = evConsIovec(tmp, 3); } (*ctx->logger)(ctl_debug, "%s: [%d] %s", me, sess->outbuf.used, sess->outbuf.text); @@ -369,7 +376,8 @@ ctl_sendhelp(struct ctl_sess *sess, u_int code) { sess->helpcode = code; sess->verb = &fakehelpverb; - ctl_morehelp(ctx, sess, NULL, me, CTL_MORE, (void *)ctx->verbs, NULL); + ctl_morehelp(ctx, sess, NULL, me, CTL_MORE, + (const void *)ctx->verbs, NULL); } void * @@ -397,6 +405,10 @@ ctl_accept(evContext lev, void *uap, int fd, struct ctl_sess *sess = NULL; char tmp[MAX_NTOP]; + UNUSED(lev); + UNUSED(lalen); + UNUSED(ralen); + if (fd < 0) { (*ctx->logger)(ctl_error, "%s: accept: %s", me, strerror(errno)); @@ -404,7 +416,7 @@ ctl_accept(evContext lev, void *uap, int fd, } if (ctx->cur_sess == ctx->max_sess) { (*ctx->logger)(ctl_error, "%s: %s: too many control sessions", - me, ctl_sa_ntop((struct sockaddr *)rav, + me, ctl_sa_ntop((const struct sockaddr *)rav, tmp, sizeof tmp, ctx->logger)); (void) close(fd); @@ -432,11 +444,11 @@ ctl_accept(evContext lev, void *uap, int fd, sess->rdtiID.opaque = NULL; sess->respctx = NULL; sess->csctx = NULL; - if (((struct sockaddr *)rav)->sa_family == AF_UNIX) - ctl_sa_copy((struct sockaddr *)lav, + if (((const struct sockaddr *)rav)->sa_family == AF_UNIX) + ctl_sa_copy((const struct sockaddr *)lav, (struct sockaddr *)&sess->sa); else - ctl_sa_copy((struct sockaddr *)rav, + ctl_sa_copy((const struct sockaddr *)rav, (struct sockaddr *)&sess->sa); sess->donefunc = NULL; buffer_init(sess->inbuf); @@ -447,7 +459,7 @@ ctl_accept(evContext lev, void *uap, int fd, (*ctx->logger)(ctl_debug, "%s: %s: accepting (fd %d)", me, address_expr, sess->sock); (*ctx->connverb->func)(ctx, sess, ctx->connverb, "", 0, - (struct sockaddr *)rav, ctx->uctx); + (const struct sockaddr *)rav, ctx->uctx); } static void @@ -614,6 +626,10 @@ ctl_wrtimeout(evContext lev, void *uap, struct ctl_sess *sess = uap; struct ctl_sctx *ctx = sess->ctx; char tmp[MAX_NTOP]; + + UNUSED(lev); + UNUSED(due); + UNUSED(itv); REQUIRE(sess->state == writing); sess->wrtiID.opaque = NULL; @@ -638,6 +654,10 @@ ctl_rdtimeout(evContext lev, void *uap, struct ctl_sctx *ctx = sess->ctx; char tmp[MAX_NTOP]; + UNUSED(lev); + UNUSED(due); + UNUSED(itv); + REQUIRE(sess->state == reading); sess->rdtiID.opaque = NULL; (*ctx->logger)(ctl_warning, "%s: %s: timeout, closing", @@ -699,6 +719,9 @@ ctl_writedone(evContext lev, void *uap, int fd, int bytes) { char tmp[MAX_NTOP]; int save_errno = errno; + UNUSED(lev); + UNUSED(uap); + REQUIRE(sess->state == writing); REQUIRE(fd == sess->sock); REQUIRE(sess->wrtiID.opaque != NULL); @@ -731,9 +754,14 @@ ctl_writedone(evContext lev, void *uap, int fd, int bytes) { static void ctl_morehelp(struct ctl_sctx *ctx, struct ctl_sess *sess, const struct ctl_verb *verb, const char *text, - u_int respflags, void *respctx, void *uctx) + u_int respflags, const void *respctx, void *uctx) { - struct ctl_verb *this = respctx, *next = this + 1; + const struct ctl_verb *this = respctx, *next = this + 1; + + UNUSED(ctx); + UNUSED(verb); + UNUSED(text); + UNUSED(uctx); REQUIRE(!lastverb_p(this)); REQUIRE((respflags & CTL_MORE) != 0); diff --git a/contrib/bind/lib/isc/ev_connects.c b/contrib/bind/lib/isc/ev_connects.c index 5378665..5be432a 100644 --- a/contrib/bind/lib/isc/ev_connects.c +++ b/contrib/bind/lib/isc/ev_connects.c @@ -20,7 +20,7 @@ */ #if !defined(LINT) && !defined(CODECENTER) -static const char rcsid[] = "$Id: ev_connects.c,v 8.27 2000/11/14 01:10:37 vixie Exp $"; +static const char rcsid[] = "$Id: ev_connects.c,v 8.32 2001/07/03 13:26:35 marka Exp $"; #endif /* Import. */ @@ -30,6 +30,7 @@ static const char rcsid[] = "$Id: ev_connects.c,v 8.27 2000/11/14 01:10:37 vixie #include <sys/types.h> #include <sys/socket.h> +#include <sys/ioctl.h> #include <unistd.h> @@ -77,7 +78,12 @@ evListen(evContext opaqueCtx, int fd, int maxconn, * incorrectly. */ if ((mode & PORT_NONBLOCK) == 0) { +#ifdef USE_FIONBIO_IOCTL + int on = 1; + OK(ioctl(fd, FIONBIO, (char *)&on)); +#else OK(fcntl(fd, F_SETFL, mode | PORT_NONBLOCK)); +#endif new->flags |= EV_CONN_BLOCK; } OK(listen(fd, maxconn)); @@ -103,7 +109,7 @@ evListen(evContext opaqueCtx, int fd, int maxconn, } int -evConnect(evContext opaqueCtx, int fd, void *ra, int ralen, +evConnect(evContext opaqueCtx, int fd, const void *ra, int ralen, evConnFunc func, void *uap, evConnID *id) { evContext_p *ctx = opaqueCtx.opaque; @@ -160,8 +166,14 @@ evCancelConn(evContext opaqueCtx, evConnID id) { if (mode == -1) { if (errno != EBADF) return (-1); - } else + } else { +#ifdef USE_FIONBIO_IOCTL + int on = 1; + OK(ioctl(this->fd, FIONBIO, (char *)&on)); +#else OK(fcntl(this->fd, F_SETFL, mode | PORT_NONBLOCK)); +#endif + } } /* Unlink from ctx->conns. */ @@ -275,7 +287,8 @@ listener(evContext opaqueCtx, void *uap, int fd, int evmask) { struct sockaddr_un un; #endif } la, ra; - int new, lalen = 0, ralen; + int new; + ISC_SOCKLEN_T lalen = 0, ralen; REQUIRE((evmask & EV_READ) != 0); ralen = sizeof ra; @@ -309,13 +322,15 @@ connector(evContext opaqueCtx, void *uap, int fd, int evmask) { struct sockaddr_un un; #endif } la, ra; - int lalen, ralen; + ISC_SOCKLEN_T lalen, ralen; char buf[1]; void *conn_uap; evConnFunc conn_func; evConnID id; int socket_errno = 0; - int optlen; + ISC_SOCKLEN_T optlen; + + UNUSED(evmask); lalen = sizeof la; ralen = sizeof ra; diff --git a/contrib/bind/lib/isc/ev_files.c b/contrib/bind/lib/isc/ev_files.c index 434385c..c6bcab6 100644 --- a/contrib/bind/lib/isc/ev_files.c +++ b/contrib/bind/lib/isc/ev_files.c @@ -20,7 +20,7 @@ */ #if !defined(LINT) && !defined(CODECENTER) -static const char rcsid[] = "$Id: ev_files.c,v 1.19 1999/10/07 20:44:04 vixie Exp $"; +static const char rcsid[] = "$Id: ev_files.c,v 1.21 2001/11/01 05:35:46 marka Exp $"; #endif #include "port_before.h" @@ -28,6 +28,7 @@ static const char rcsid[] = "$Id: ev_files.c,v 1.19 1999/10/07 20:44:04 vixie Ex #include <sys/types.h> #include <sys/time.h> +#include <sys/ioctl.h> #include <errno.h> #include <fcntl.h> @@ -56,9 +57,9 @@ evSelectFD(evContext opaqueCtx, "evSelectFD(ctx %#x, fd %d, mask 0x%x, func %#x, uap %#x)\n", ctx, fd, eventmask, func, uap); if (eventmask == 0 || (eventmask & ~EV_MASK_ALL) != 0) - ERR(EINVAL); + EV_ERR(EINVAL); if (fd > ctx->highestFD) - ERR(EINVAL); + EV_ERR(EINVAL); OK(mode = fcntl(fd, F_GETFL, NULL)); /* side effect: validate fd. */ /* @@ -72,7 +73,12 @@ evSelectFD(evContext opaqueCtx, if (mode & PORT_NONBLOCK) FD_SET(fd, &ctx->nonblockBefore); else { +#ifdef USE_FIONBIO_IOCTL + int on = 1; + OK(ioctl(fd, FIONBIO, (char *)&on)); +#else OK(fcntl(fd, F_SETFL, mode | PORT_NONBLOCK)); +#endif FD_CLR(fd, &ctx->nonblockBefore); } } @@ -84,7 +90,7 @@ evSelectFD(evContext opaqueCtx, * same context. */ if (id != NULL && FindFD(ctx, fd, eventmask) != NULL) - ERR(ETOOMANYREFS); + EV_ERR(ETOOMANYREFS); /* Allocate and fill. */ OKNEW(id); @@ -166,7 +172,7 @@ evDeselectFD(evContext opaqueCtx, evFileID opaqueID) { /* Get the mode. Unless the file has been closed, errors are bad. */ mode = fcntl(del->fd, F_GETFL, NULL); if (mode == -1 && errno != EBADF) - ERR(errno); + EV_ERR(errno); /* Remove from the list of files. */ if (del->prev != NULL) @@ -197,7 +203,12 @@ evDeselectFD(evContext opaqueCtx, evFileID opaqueID) { * this fcntl() fails since (a) we've already done the work * and (b) the caller didn't ask us anything about O_NONBLOCK. */ +#ifdef USE_FIONBIO_IOCTL + int off = 1; + (void) ioctl(del->fd, FIONBIO, (char *)&off); +#else (void) fcntl(del->fd, F_SETFL, mode & ~PORT_NONBLOCK); +#endif } /* diff --git a/contrib/bind/lib/isc/ev_streams.c b/contrib/bind/lib/isc/ev_streams.c index b25a666..a301720 100644 --- a/contrib/bind/lib/isc/ev_streams.c +++ b/contrib/bind/lib/isc/ev_streams.c @@ -20,7 +20,7 @@ */ #if !defined(LINT) && !defined(CODECENTER) -static const char rcsid[] = "$Id: ev_streams.c,v 8.21 1999/10/07 20:44:04 vixie Exp $"; +static const char rcsid[] = "$Id: ev_streams.c,v 8.22 2001/05/29 05:49:29 marka Exp $"; #endif #include "port_before.h" @@ -125,6 +125,8 @@ int evTimeRW(evContext opaqueCtx, evStreamID id, evTimerID timer) /*ARGSUSED*/ { evStream *str = id.opaque; + UNUSED(opaqueCtx); + str->timer = timer; str->flags |= EV_STR_TIMEROK; return (0); @@ -134,6 +136,8 @@ int evUntimeRW(evContext opaqueCtx, evStreamID id) /*ARGSUSED*/ { evStream *str = id.opaque; + UNUSED(opaqueCtx); + str->flags &= ~EV_STR_TIMEROK; return (0); } @@ -218,7 +222,7 @@ copyvec(evStream *str, const struct iovec *iov, int iocnt) { static void consume(evStream *str, size_t bytes) { while (bytes > 0) { - if (bytes < str->iovCur->iov_len) { + if (bytes < (size_t)str->iovCur->iov_len) { str->iovCur->iov_len -= bytes; str->iovCur->iov_base = (void *) ((u_char *)str->iovCur->iov_base + bytes); @@ -257,6 +261,8 @@ writable(evContext opaqueCtx, void *uap, int fd, int evmask) { evStream *str = uap; int bytes; + UNUSED(evmask); + bytes = writev(fd, str->iovCur, str->iovCurCount); if (bytes > 0) { if ((str->flags & EV_STR_TIMEROK) != 0) @@ -278,6 +284,8 @@ readable(evContext opaqueCtx, void *uap, int fd, int evmask) { evStream *str = uap; int bytes; + UNUSED(evmask); + bytes = readv(fd, str->iovCur, str->iovCurCount); if (bytes > 0) { if ((str->flags & EV_STR_TIMEROK) != 0) diff --git a/contrib/bind/lib/isc/ev_timers.c b/contrib/bind/lib/isc/ev_timers.c index e5e5684..03436c6 100644 --- a/contrib/bind/lib/isc/ev_timers.c +++ b/contrib/bind/lib/isc/ev_timers.c @@ -20,7 +20,7 @@ */ #if !defined(LINT) && !defined(CODECENTER) -static const char rcsid[] = "$Id: ev_timers.c,v 1.30 2001/02/12 23:13:48 marka Exp $"; +static const char rcsid[] = "$Id: ev_timers.c,v 1.32 2001/11/01 05:35:47 marka Exp $"; #endif /* Import. */ @@ -201,7 +201,7 @@ evClearTimer(evContext opaqueCtx, evTimerID id) { } if (heap_element(ctx->timers, del->index) != del) - ERR(ENOENT); + EV_ERR(ENOENT); if (heap_delete(ctx->timers, del->index) < 0) return (-1); @@ -229,7 +229,7 @@ evResetTimer(evContext opaqueCtx, int result=0; if (heap_element(ctx->timers, timer->index) != timer) - ERR(ENOENT); + EV_ERR(ENOENT); old_due = timer->due; @@ -332,6 +332,9 @@ evTouchIdleTimer(evContext opaqueCtx, evTimerID id) { heap_context evCreateTimers(const evContext_p *ctx) { + + UNUSED(ctx); + return (heap_new(due_sooner, set_index, 2048)); } @@ -363,6 +366,9 @@ set_index(void *what, int index) { static void free_timer(void *what, void *uap) { evTimer *t = what; + + UNUSED(uap); + FREE(t); } @@ -388,6 +394,9 @@ idle_timeout(evContext opaqueCtx, evContext_p *ctx = opaqueCtx.opaque; idle_timer *this = uap; struct timespec idle; + + UNUSED(due); + UNUSED(inter); idle = evSubTime(ctx->lastEventTime, this->lastTouched); if (evCmpTime(idle, this->max_idle) >= 0) { diff --git a/contrib/bind/lib/isc/eventlib.c b/contrib/bind/lib/isc/eventlib.c index cea98ac..0e52733 100644 --- a/contrib/bind/lib/isc/eventlib.c +++ b/contrib/bind/lib/isc/eventlib.c @@ -20,7 +20,7 @@ */ #if !defined(LINT) && !defined(CODECENTER) -static const char rcsid[] = "$Id: eventlib.c,v 1.45 2000/02/04 07:25:39 vixie Exp $"; +static const char rcsid[] = "$Id: eventlib.c,v 1.46 2001/11/01 05:35:48 marka Exp $"; #endif #include "port_before.h" @@ -193,7 +193,7 @@ evGetNext(evContext opaqueCtx, evEvent *opaqueEv, int options) { /* Ensure that exactly one of EV_POLL or EV_WAIT was specified. */ x = ((options & EV_POLL) != 0) + ((options & EV_WAIT) != 0); if (x != 1) - ERR(EINVAL); + EV_ERR(EINVAL); /* Get the time of day. We'll do this again after select() blocks. */ ctx->lastEventTime = evNowTime(); @@ -248,7 +248,7 @@ evGetNext(evContext opaqueCtx, evEvent *opaqueEv, int options) { /* Are there any events at all? */ if ((options & EV_WAIT) != 0 && !nextTimer && ctx->fdMax == -1) - ERR(ENOENT); + EV_ERR(ENOENT); /* Figure out what select()'s timeout parameter should be. */ if ((options & EV_POLL) != 0) { @@ -343,11 +343,11 @@ evGetNext(evContext opaqueCtx, evEvent *opaqueEv, int options) { } abort(); } - ERR(pselect_errno); + EV_ERR(pselect_errno); } if (x == 0 && (nextTimer == NULL || !timerPast) && (options & EV_POLL)) - ERR(EWOULDBLOCK); + EV_ERR(EWOULDBLOCK); ctx->fdCount = x; #ifdef EVENTLIB_TIME_CHECKS ctx->lastFdCount = x; diff --git a/contrib/bind/lib/isc/eventlib.mdoc b/contrib/bind/lib/isc/eventlib.mdoc index 202b1cb..e95871c 100644 --- a/contrib/bind/lib/isc/eventlib.mdoc +++ b/contrib/bind/lib/isc/eventlib.mdoc @@ -1,4 +1,4 @@ -.\" $Id: eventlib.mdoc,v 1.20 1999/08/18 22:09:04 vixie Exp $ +.\" $Id: eventlib.mdoc,v 1.22 2001/12/28 04:24:22 marka Exp $ .\" .\"Copyright (c) 1995-1999 by Internet Software Consortium .\" @@ -70,17 +70,17 @@ .Sh SYNOPSIS .Fd #include <isc/eventlib.h> .Ft typedef void -.Fn (*evConnFunc) "evContext ctx" "void *uap" "int fd" \ +.Fn \*(lp*evConnFunc\*(rp "evContext ctx" "void *uap" "int fd" \ "const void *la" "int lalen" "const void *ra" "int ralen" .Ft typedef void -.Fn (*evTimerFunc) "evContext ctx" "void *uap" \ +.Fn \*(lp*evTimerFunc\*(rp "evContext ctx" "void *uap" \ "struct timespec due" "struct timespec inter" .Ft typedef void -.Fn (*evFileFunc) "evContext ctx" "void *uap" "int fd" "int eventmask" +.Fn \*(lp*evFileFunc\*(rp "evContext ctx" "void *uap" "int fd" "int eventmask" .Ft typedef void -.Fn (*evStreamFunc) "evContext ctx" "void *uap" "int fd" "int bytes" +.Fn \*(lp*evStreamFunc\*(rp "evContext ctx" "void *uap" "int fd" "int bytes" .Ft typedef void -.Fn (*evWaitFunc) "evContext ctx" "void *uap" "const void *tag" +.Fn \*(lp*evWaitFunc\*(rp "evContext ctx" "void *uap" "const void *tag" .Ft int .Fn evCreate "evContext *ctx" .Ft int @@ -197,7 +197,7 @@ The function creates an event context which is needed by all the other functions in this library. All information used internally by this library is bound to this context, rather than to static storage. This makes the library -.Dq thread safe, +.Dq thread safe , and permits other library functions to use events without disrupting the application's use of events. .Pp @@ -325,7 +325,7 @@ The function adds two .Dq Fa struct timespec values and returns the result as a -.Dq Fa struct timespec. +.Dq Fa struct timespec . .Pp The function .Fn evSubTime @@ -334,7 +334,7 @@ subtracts its second argument from its first .Dq Fa struct timespec argument and returns the result as a -.Dq Fa struct timespec. +.Dq Fa struct timespec . .Pp The function .Fn evCmpTime @@ -384,15 +384,15 @@ argument. The event will be delivered at absolute time and then if time .Fa inter is not equal to -.Dq Fa evConsTime(0,0) , +.Dq Fn evConsTime 0 0 , subsequently at intervals equal to time .Fa inter . As a special case, specifying a .Fa due argument equal to -.Dq Fa evConsTime(0,0) +.Dq Fn evConsTime 0 0 means -.Dq due immediately. +.Dq due immediately . The .Fa opaqueID argument, if specified as a value other than @@ -406,9 +406,8 @@ Note that in a timer (which has an .Fa inter argument equal to -.Dq Fa evConsTime(0,0) -.\" putting the ) after the Dq Fa arg did not work well. --vix -) the user function +.Dq Fa evConsTime(0,0) ) +the user function .Fa func should deallocate any dynamic memory that is uniquely bound to the .Fa uap , @@ -711,7 +710,7 @@ initiates an outgoing connection on to destination address .Fa ra (whose length is -.Fa ralen ). +.Fa ralen ) . When the connection is complete, .Fa func will be called with @@ -719,7 +718,7 @@ will be called with as one of its arguments. The argument .Fa fd to -.Fn (*func)() +.Fn \*(lp*func\*(rp will be .Fa -1 if an error occurred that prevented this connection from completing diff --git a/contrib/bind/lib/isc/eventlib_p.h b/contrib/bind/lib/isc/eventlib_p.h index b4d7ecc..78f0100 100644 --- a/contrib/bind/lib/isc/eventlib_p.h +++ b/contrib/bind/lib/isc/eventlib_p.h @@ -18,7 +18,7 @@ /* eventlib_p.h - private interfaces for eventlib * vix 09sep95 [initial] * - * $Id: eventlib_p.h,v 1.28 2000/02/04 08:28:34 vixie Exp $ + * $Id: eventlib_p.h,v 1.30 2001/11/01 05:35:50 marka Exp $ */ #ifndef _EVENTLIB_P_H @@ -43,8 +43,8 @@ #include <isc/memcluster.h> #define EV_MASK_ALL (EV_READ | EV_WRITE | EV_EXCEPT) -#define ERR(e) return (errno = (e), -1) -#define OK(x) if ((x) < 0) ERR(errno); else (void)NULL +#define EV_ERR(e) return (errno = (e), -1) +#define OK(x) if ((x) < 0) EV_ERR(errno); else (void)NULL #define NEW(p) if (((p) = memget(sizeof *(p))) != NULL) \ FILL(p); \ @@ -85,7 +85,7 @@ typedef struct evAccept { struct sockaddr_un un; #endif } la; - int lalen; + ISC_SOCKLEN_T lalen; union { struct sockaddr sa; struct sockaddr_in in; @@ -93,7 +93,7 @@ typedef struct evAccept { struct sockaddr_un un; #endif } ra; - int ralen; + ISC_SOCKLEN_T ralen; int ioErrno; evConn * conn; LINK(struct evAccept) link; diff --git a/contrib/bind/lib/isc/heap.mdoc b/contrib/bind/lib/isc/heap.mdoc index 6e0384d..4b60e91 100644 --- a/contrib/bind/lib/isc/heap.mdoc +++ b/contrib/bind/lib/isc/heap.mdoc @@ -1,4 +1,4 @@ -.\" $Id: heap.mdoc,v 8.6 2000/11/15 02:03:52 marka Exp $ +.\" $Id: heap.mdoc,v 8.7 2001/08/08 07:50:24 marka Exp $ .\" .\"Copyright (c) 1997,1999 by Internet Software Consortium. .\" @@ -15,7 +15,7 @@ .\"ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS .\"SOFTWARE. .\" -.Dd Jan 1, 1997 +.Dd January 1, 1997 .\"Os OPERATING_SYSTEM [version/release] .Os BSD 4 .Dt HEAP @SYSCALL_EXT@ @@ -52,10 +52,9 @@ These functions implement heap\-based priority queues. The user defines a priority scheme, and provides a function for comparison of the priority of heap elements -.Po see the description of the +(see the description of the .Ft heap_higher_priority_func -function pointer, below -.Pc . +function pointer, below). .Pp Each of the functions depends upon the .Ft heap_context @@ -163,9 +162,8 @@ into the appropriate place (priority\-wise) in the .Ft heap indicated by .Fa ctx -.Po a pointer to a -.Ft heap_context -.Pc . +(a pointer to a +.Ft heap_context ) . If .No non\- Ns Dv NULL , the user-defined @@ -189,7 +187,9 @@ element onward via the priority as determined by the user function pointed to by .Ft higher_priority function pointer -.Pq see description of Fn heap_new, No above . +(see description of +.Fn heap_new , +above). .Pp .Fn heap_increased .Pp @@ -233,7 +233,7 @@ a or if the .Fa higher_priority function pointer is -.Dv NULL; +.Dv NULL ; otherwise, a valid .Ft heap_context .Ns . @@ -347,14 +347,24 @@ please refer to .Sh SEE ALSO .Xr malloc 3 , .Xr realloc 3 . -.Pp -Cormen, Leiserson, and Rivest, -.Sy Introduction to Algorithms, -MIT Press / McGraw Hill, 1990, ISBN 0\-262\-03141\-8, chapter 7. -.Pp -Sedgewick, -.Sy Algorithms, -2nd ed'n, Addison\-Wesley, 1988, ISBN 0\-201\-06673\-4, chapter 11. +.Rs +.%A Cormen +.%A Leiserson +.%A Rivest +.%B Introduction to Algorithms +.%Q "MIT Press / McGraw Hill" +.%D 1990 +.%O ISBN 0\-262\-03141\-8 +.%P chapter 7 +.Re +.Rs +.%A Sedgewick +.%B Algorithms, 2nd ed'n +.%Q Addison\-Wesley +.%D 1988 +.%O ISBN 0\-201\-06673\-4 +.%P chapter 11 +.Re .\" .Sh STANDARDS .\" .Sh HISTORY .Sh AUTHORS diff --git a/contrib/bind/lib/isc/hex.c b/contrib/bind/lib/isc/hex.c new file mode 100644 index 0000000..2239796 --- /dev/null +++ b/contrib/bind/lib/isc/hex.c @@ -0,0 +1,116 @@ +/* + * Copyright (c) 2001 by Internet Software Consortium. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS + * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE + * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS + * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + * SOFTWARE. + */ + +#include <port_before.h> +#include <ctype.h> +#include <stdio.h> +#include <string.h> +#include <isc/misc.h> +#include <port_after.h> + +static const char hex[17] = "0123456789abcdef"; + +int +isc_gethexstring(unsigned char *buf, size_t len, int count, FILE *fp, + int *multiline) +{ + int c, n; + unsigned char x; + char *s; + int result = count; + + x = 0; /* silence compiler */ + n = 0; + while (count > 0) { + c = fgetc(fp); + + if ((c == EOF) || + (c == '\n' && !*multiline) || + (c == '(' && *multiline) || + (c == ')' && !*multiline)) + goto formerr; + /* comment */ + if (c == ';') { + while ((c = fgetc(fp)) != EOF && c != '\n') + /* empty */ + if (c == '\n' && *multiline) + continue; + goto formerr; + } + /* white space */ + if (c == ' ' || c == '\t' || c == '\n' || c == '\r') + continue; + /* multiline */ + if ('(' == c || c == ')') { + *multiline = (c == '(' /*)*/); + continue; + } + if ((s = strchr(hex, tolower(c))) == NULL) + goto formerr; + x = (x<<4) | (s - hex); + if (++n == 2) { + if (len > 0) { + *buf++ = x; + len--; + } else + result = -1; + count--; + n = 0; + } + } + return (result); + + formerr: + if (c == '\n') + ungetc(c, fp); + return (-1); +} + +void +isc_puthexstring(FILE *fp, const unsigned char *buf, size_t buflen, + size_t len1, size_t len2, const char *sep) +{ + size_t i = 0; + + if (len1 < 4) + len1 = 4; + if (len2 < 4) + len2 = 4; + while (buflen > 0) { + fputc(hex[(buf[0]>>4)&0xf], fp); + fputc(hex[buf[0]&0xf], fp); + i += 2; + buflen--; + buf++; + if (i >= len1 && sep != NULL) { + fputs(sep, fp); + i = 0; + len1 = len2; + } + } +} + +void +isc_tohex(const unsigned char *buf, size_t buflen, char *t) { + while (buflen > 0) { + *t++ = hex[(buf[0]>>4)&0xf]; + *t++ = hex[buf[0]&0xf]; + buf++; + buflen--; + } + *t = '\0'; +} diff --git a/contrib/bind/lib/isc/logging.c b/contrib/bind/lib/isc/logging.c index 0d9037f..ca7ea04 100644 --- a/contrib/bind/lib/isc/logging.c +++ b/contrib/bind/lib/isc/logging.c @@ -16,7 +16,7 @@ */ #if !defined(LINT) && !defined(CODECENTER) -static const char rcsid[] = "$Id: logging.c,v 8.28 2000/12/23 08:14:54 vixie Exp $"; +static const char rcsid[] = "$Id: logging.c,v 8.31 2001/06/18 14:44:03 marka Exp $"; #endif /* not lint */ #include "port_before.h" @@ -57,8 +57,9 @@ static const int syslog_priority[] = { LOG_DEBUG, LOG_INFO, LOG_NOTICE, static const char *months[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; -static char *level_text[] = { "info: ", "notice: ", "warning: ", "error: ", - "critical: " }; +static const char *level_text[] = { + "info: ", "notice: ", "warning: ", "error: ", "critical: " +}; static void version_rename(log_channel chan) { @@ -177,6 +178,19 @@ log_close_stream(log_channel chan) { return (0); } +void +log_close_debug_channels(log_context lc) { + log_channel_list lcl; + int i; + + for (i = 0; i < lc->num_categories; i++) + for (lcl = lc->categories[i]; lcl != NULL; lcl = lcl->next) + if (lcl->channel->type == log_file && + lcl->channel->out.file.stream != NULL && + lcl->channel->flags & LOG_REQUIRE_DEBUG) + (void)log_close_stream(lcl->channel); +} + FILE * log_get_stream(log_channel chan) { if (chan == NULL || chan->type != log_file) { @@ -268,8 +282,8 @@ log_vwrite(log_context lc, int category, int level, const char *format, log_channel chan; struct timeval tv; struct tm *local_tm; - char *category_name; - char *level_str; + const char *category_name; + const char *level_str; char time_buf[256]; char level_buf[256]; @@ -582,7 +596,7 @@ log_new_syslog_channel(unsigned int flags, int level, int facility) { log_channel log_new_file_channel(unsigned int flags, int level, - char *name, FILE *stream, unsigned int versions, + const char *name, FILE *stream, unsigned int versions, unsigned long max_size) { log_channel chan; diff --git a/contrib/bind/lib/isc/logging.mdoc b/contrib/bind/lib/isc/logging.mdoc index 47d4312..8d8d27e 100644 --- a/contrib/bind/lib/isc/logging.mdoc +++ b/contrib/bind/lib/isc/logging.mdoc @@ -1,4 +1,4 @@ -.\" $Id: logging.mdoc,v 8.4 2000/04/23 02:19:02 vixie Exp $ +.\" $Id: logging.mdoc,v 8.6 2001/12/28 04:24:23 marka Exp $ .\" .\"Copyright (c) 1995-1999 by Internet Software Consortium .\" @@ -212,7 +212,7 @@ Each category can have its own list of associated with it; we say that such a channel is .Dq in the particular category. -.Sy NOTE: +.Sy NOTE : Individual logging channels can appear in more than one category. .Pp A @@ -220,12 +220,12 @@ A is the set of all .Nm logging channels associated with the context's -.Nm categories; +.Nm categories ; thus, a particular .Nm category scheme is associated with a particular -.Nm logging context. -.Sy NOTE: +.Nm logging context . +.Sy NOTE : A logging channel may appear in more than one logging context, and in multiple categories within each logging context. .Pp @@ -325,8 +325,8 @@ type or .Dv log_file . .It Dv LOG_TRUNCATE -Truncate logging file when re-opened ( -.Fn log_open_stream +Truncate logging file when re-opened +.Fn ( log_open_stream will .Xr unlink 2 the file and then @@ -370,8 +370,8 @@ bit of the field of the logging channel structure is set), then any file with the .Dq current filename for the stream is -.X4 unlink 2 Ns -d . -.Sy NOTE: +.Xr unlink 2 Ns -d . +.Sy NOTE : If the logging file is .Em not a regular file, and either of the above operations (version numbering @@ -477,7 +477,7 @@ set and the message is not a debugging message (i.e., has a level greater than 0), then it will not be logged. Finally, if the message's priority is less important than the channel's logging level (the priority threshold), will not be logged. -.Sy NOTE: +.Sy NOTE : If a logging channel's flag has .Dv LOG_USE_CONTEXT_LEVEL set, it will use the logging context's priority, rather than its own. @@ -572,7 +572,7 @@ and .Dq Fa category_names which are supplied; the latter can be .Dv NULL . -.Sy NOTE: +.Sy NOTE : Since .Dq Fa category_names is used directly, it @@ -586,7 +586,7 @@ The function is used to free the opaque structure .Dq Va lc.opaque and its components. -.Sy NOTE: +.Sy NOTE : The .Dq Va opaque field of @@ -614,7 +614,7 @@ and is set to .Dv NULL . .Pp -.Sy NOTE: +.Sy NOTE : The function .Fn log_free_context does @@ -704,7 +704,9 @@ create a new channel of the type specified (thus, the difference in arguments); the .Dq Va type field of the new -.Dq Ft struct log_channel +.Do +.Ft struct log_channel +.Dc is always set to the appropriate value. .Pp The @@ -807,7 +809,8 @@ c) if any of or .Xr fdopen 3 fails -.Po Va errno +.Po +.Va errno is set by the call which failed .Pc . If some value other than @@ -862,7 +865,8 @@ is or .Fa category is invalid (negative or greater than or equal to -.Va lcp->num_categories ), with +.Va lcp->num_categories ) , +with .Va errno set to .Dv EINVAL ; @@ -897,7 +901,7 @@ is .Dv NULL , b) .Fa option -specifies an unknown logging option ; +specifies an unknown logging option; in either case, .Va errno is set to diff --git a/contrib/bind/lib/isc/memcluster.c b/contrib/bind/lib/isc/memcluster.c index d565c05..fcba1a3 100644 --- a/contrib/bind/lib/isc/memcluster.c +++ b/contrib/bind/lib/isc/memcluster.c @@ -24,7 +24,7 @@ #if !defined(LINT) && !defined(CODECENTER) -static const char rcsid[] = "$Id: memcluster.c,v 8.20 2001/02/13 23:14:54 marka Exp $"; +static const char rcsid[] = "$Id: memcluster.c,v 8.23 2001/06/18 14:44:05 marka Exp $"; #endif /* not lint */ #include "port_before.h" @@ -67,7 +67,7 @@ typedef struct { const char * file; int line; #endif - int size; + size_t size; fence_t fencepost; #endif } memcluster_element; @@ -173,6 +173,10 @@ __memget_record(size_t size, const char *file, int line) { #endif void *ret; +#if !defined(MEMCLUSTER_RECORD) + UNUSED(file); + UNUSED(line); +#endif if (freelists == NULL) if (meminit(0, 0) == -1) return (NULL); @@ -335,12 +339,19 @@ __memput_record(void *mem, size_t size, const char *file, int line) { size_t new_size = quantize(size); #if defined (DEBUGGING_MEMCLUSTER) memcluster_element *e; + memcluster_element *el; #ifdef MEMCLUSTER_RECORD - memcluster_element *prev, *el; + memcluster_element *prev; #endif - int fp; + fence_t fp; char *p; #endif + +#if !defined (MEMCLUSTER_RECORD) + UNUSED(file); + UNUSED(line); +#endif + REQUIRE(freelists != NULL); if (size == 0) { @@ -473,7 +484,7 @@ memstats(FILE *out) { for (i = 1; i <= max_size; i++) { if ((e = activelists[i]) != NULL) while (e != NULL) { - fprintf(out, "%s:%d %#p:%d\n", + fprintf(out, "%s:%d %p:%d\n", e->file != NULL ? e->file : "<UNKNOWN>", e->line, (char *)e + sizeof *e, e->size); @@ -483,6 +494,18 @@ memstats(FILE *out) { #endif } +int +memactive(void) { + size_t i; + + if (stats == NULL) + return (0); + for (i = 1; i <= max_size; i++) + if (stats[i].gets != 0) + return (1); + return (0); +} + /* Private. */ /* @@ -515,7 +538,7 @@ quantize(size_t size) { #if defined(DEBUGGING_MEMCLUSTER) static void check(unsigned char *a, int value, size_t len) { - int i; + size_t i; for (i = 0; i < len; i++) INSIST(a[i] == value); } diff --git a/contrib/bind/lib/isc/memcluster.mdoc b/contrib/bind/lib/isc/memcluster.mdoc index 82bfd71..c4c4588 100644 --- a/contrib/bind/lib/isc/memcluster.mdoc +++ b/contrib/bind/lib/isc/memcluster.mdoc @@ -1,4 +1,4 @@ -.\" $Id: memcluster.mdoc,v 8.2 1999/01/08 19:25:46 vixie Exp $ +.\" $Id: memcluster.mdoc,v 8.3 2001/08/08 07:50:27 marka Exp $ .\" .\"Copyright (c) 1995-1999 by Internet Software Consortium .\" @@ -20,7 +20,7 @@ .\"Os OPERATING_SYSTEM [version/release] .Os BSD 4 .\"Dt DOCUMENT_TITLE [section number] [volume] -.Dt memcluster 3 +.Dt MEMCLUSTER 3 .Sh NAME .Nm meminit , .Nm memget , @@ -192,7 +192,8 @@ the the value as mentioned in the .Sx INTERNALS subsection, above, the block is placed at the head of the free list of -.Va new_size Ns No -sized blocks. +.Va new_size Ns -sized +blocks. If the given .Fa size is zero or negative, then @@ -276,7 +277,7 @@ is generally equal to .Fa size , which has these implications: -.Bl -enum -offset -indent means that, for +.Bl -enum -offset indent .It For .Fa size diff --git a/contrib/bind/lib/isc/tree.c b/contrib/bind/lib/isc/tree.c index 90ba146..65025e4 100644 --- a/contrib/bind/lib/isc/tree.c +++ b/contrib/bind/lib/isc/tree.c @@ -1,5 +1,5 @@ #ifndef LINT -static const char rcsid[] = "$Id: tree.c,v 8.9 1999/01/08 19:25:47 vixie Exp $"; +static const char rcsid[] = "$Id: tree.c,v 8.10 2001/11/01 05:33:46 marka Exp $"; #endif /* @@ -101,7 +101,7 @@ tree_init(tree **ppr_tree) { } tree_t -tree_srch(tree **ppr_tree, int (*pfi_compare)(), tree_t p_user) { +tree_srch(tree **ppr_tree, int (*pfi_compare)(tree_t, tree_t), tree_t p_user) { ENTER("tree_srch") if (*ppr_tree) { @@ -128,7 +128,7 @@ tree_srch(tree **ppr_tree, int (*pfi_compare)(), tree_t p_user) { } tree_t -tree_add(tree **ppr_tree, int (*pfi_compare)(), +tree_add(tree **ppr_tree, int (*pfi_compare)(tree_t, tree_t), tree_t p_user, void (*pfv_uar)()) { int i_balance = FALSE; @@ -140,7 +140,7 @@ tree_add(tree **ppr_tree, int (*pfi_compare)(), } int -tree_delete(tree **ppr_p, int (*pfi_compare)(), +tree_delete(tree **ppr_p, int (*pfi_compare)(tree_t, tree_t), tree_t p_user, void (*pfv_uar)()) { int i_balance = FALSE, i_uar_called = FALSE; @@ -151,7 +151,7 @@ tree_delete(tree **ppr_p, int (*pfi_compare)(), } int -tree_trav(tree **ppr_tree, int (*pfi_uar)()) { +tree_trav(tree **ppr_tree, int (*pfi_uar)(tree_t)) { ENTER("tree_trav") if (!*ppr_tree) @@ -167,7 +167,7 @@ tree_trav(tree **ppr_tree, int (*pfi_uar)()) { } void -tree_mung(tree **ppr_tree, void (*pfv_uar)()) { +tree_mung(tree **ppr_tree, void (*pfv_uar)(tree_t)) { ENTER("tree_mung") if (*ppr_tree) { tree_mung(&(**ppr_tree).left, pfv_uar); @@ -182,7 +182,7 @@ tree_mung(tree **ppr_tree, void (*pfv_uar)()) { static tree * sprout(tree **ppr, tree_t p_data, int *pi_balance, - int (*pfi_compare)(), void (*pfv_delete)()) + int (*pfi_compare)(tree_t, tree_t), void (*pfv_delete)(tree_t)) { tree *p1, *p2, *sub; int cmp; @@ -335,8 +335,8 @@ sprout(tree **ppr, tree_t p_data, int *pi_balance, } static int -delete(tree **ppr_p, int (*pfi_compare)(), tree_t p_user, - void (*pfv_uar)(), int *pi_balance, int *pi_uar_called) +delete(tree **ppr_p, int (*pfi_compare)(tree_t, tree_t), tree_t p_user, + void (*pfv_uar)(tree_t), int *pi_balance, int *pi_uar_called) { tree *pr_q; int i_comp, i_ret; @@ -390,7 +390,7 @@ delete(tree **ppr_p, int (*pfi_compare)(), tree_t p_user, static void del(tree **ppr_r, int *pi_balance, tree **ppr_q, - void (*pfv_uar)(), int *pi_uar_called) + void (*pfv_uar)(tree_t), int *pi_uar_called) { ENTER("del") diff --git a/contrib/bind/lib/isc/tree.mdoc b/contrib/bind/lib/isc/tree.mdoc index 422344e..43d1b7e 100644 --- a/contrib/bind/lib/isc/tree.mdoc +++ b/contrib/bind/lib/isc/tree.mdoc @@ -1,4 +1,4 @@ -.\" $Id: tree.mdoc,v 8.2 1999/01/08 19:25:48 vixie Exp $ +.\" $Id: tree.mdoc,v 8.3 2001/08/08 07:50:28 marka Exp $ .\" .\"Copyright (c) 1995-1999 by Internet Software Consortium .\" @@ -32,15 +32,15 @@ .Ft void * .Fn tree_srch "void **tree" "int (*compare)()" "void *data" .Ft void -.Fn tree_add(tree, compare, data, del_uar) "void **tree" "int (*compare)()" \ +.Fn tree_add "void **tree" "int (*compare)()" \ "void *data" "void (*del_uar)()" .Ft int -.Fn tree_delete(tree, compare, data, del_uar) "void **tree" "int (*compare)()" \ +.Fn tree_delete "void **tree" "int (*compare)()" \ "void *data" "void (*del_uar)()" .Ft int -.Fn tree_trav(tree, trav_uar) "void **tree" "int (*trav_uar)()" +.Fn tree_trav "void **tree" "int (*trav_uar)()" .Ft void -.Fn tree_mung(tree, del_uar) "void **tree" "void (*del_uar)()" +.Fn tree_mung "void **tree" "void (*del_uar)()" .Sh DESCRIPTION These functions create and manipulate a balanced binary (AVL) tree. Each node of the tree contains the expected left & right subtree pointers, a short int @@ -88,19 +88,19 @@ returns 0. inserts or replaces a node in the specified tree. The tree specified by .Dq Fa tree is searched as in -.Fn tree_srch, +.Fn tree_srch , and if a node is found to match -.Dq Fa data, +.Dq Fa data , then the .Fn del_uar function, if non\-\s-2NULL\s+2, is called with the address of the user data block for the node (this routine should deallocate any dynamic memory which is referenced exclusively by the node); the user data pointer for the node is then replaced by the value of -.Dq Fa data. +.Dq Fa data . If no node is found to match, a new node is added (which may or may not cause a transparent rebalance operation), with a user data pointer equal to -.Dq Fa data. +.Dq Fa data . A rebalance may or may not occur, depending on where the node is added and what the rest of the tree looks like. .Fn Tree_add @@ -110,7 +110,7 @@ pointer unless catastrophe occurs in which case it will return \s-2NULL\s+2. .Pp .Fn Tree_delete deletes a node from -.Dq Fa tree. +.Dq Fa tree . A rebalance may or may not occur, depending on where the node is removed from and what the rest of the tree looks like. .Fn Tree_delete @@ -118,7 +118,7 @@ returns TRUE if a node was deleted, FALSE otherwise. .Pp .Fn Tree_trav traverses all of -.Dq Fa tree, +.Dq Fa tree , calling .Fn trav_uar with the address of each user data block. If @@ -132,7 +132,7 @@ will return TRUE. .Pp .Fn Tree_mung deletes every node in -.Dq Fa tree, +.Dq Fa tree , calling .Fn del_uar (if it is not \s-2NULL\s+2) with the user data address from each node (see diff --git a/contrib/bind/lib/nameser/Makefile b/contrib/bind/lib/nameser/Makefile index 1ab67ef..f283e1c 100644 --- a/contrib/bind/lib/nameser/Makefile +++ b/contrib/bind/lib/nameser/Makefile @@ -15,7 +15,7 @@ # SOFTWARE. # -# $Id: Makefile,v 8.21 2000/12/23 08:03:02 vixie Exp $ +# $Id: Makefile,v 8.22 2001/08/14 05:58:09 marka Exp $ # these are only appropriate for BSD 4.4 or derivatives, and are used in # development. normal builds will be done in the top level directory and @@ -60,7 +60,7 @@ ${LIBBIND}: ${OBJS} ${RANLIB} ${LIBBIND} .c.${O}: - if test ! -d ${THREADED} ; then mkdir ${THREADED} ; else true ; fi + mkdir ${THREADED} 2> /dev/null || test -d ${THREADED} -a -w ${THREADED} ${CC} ${CPPFLAGS} ${CFLAGS} ${BOUNDS} ${REENTRANT} -c $*.c \ -o ${THREADED}/$*.${O} -${LDS} ${LD} ${LD_LIBFLAGS} ${THREADED}/$*.${O} \ diff --git a/contrib/bind/lib/nameser/ns_date.c b/contrib/bind/lib/nameser/ns_date.c index da593a5..d4ec49e 100644 --- a/contrib/bind/lib/nameser/ns_date.c +++ b/contrib/bind/lib/nameser/ns_date.c @@ -16,7 +16,7 @@ */ #ifndef lint -static const char rcsid[] = "$Id: ns_date.c,v 1.2 1999/10/13 16:39:35 vixie Exp $"; +static const char rcsid[] = "$Id: ns_date.c,v 1.3 2001/05/29 05:49:34 marka Exp $"; #endif /* Import. */ @@ -116,7 +116,7 @@ datepart(const char *buf, int size, int min, int max, int *errp) { int i; for (i = 0; i < size; i++) { - if (!isdigit(buf[i])) + if (!isdigit((unsigned char)(buf[i]))) *errp = 1; result = (result * 10) + buf[i] - '0'; } diff --git a/contrib/bind/lib/nameser/ns_name.c b/contrib/bind/lib/nameser/ns_name.c index 2424eed..cf371b6 100644 --- a/contrib/bind/lib/nameser/ns_name.c +++ b/contrib/bind/lib/nameser/ns_name.c @@ -16,7 +16,7 @@ */ #ifndef lint -static const char rcsid[] = "$Id: ns_name.c,v 8.15 2000/03/30 22:53:46 vixie Exp $"; +static const char rcsid[] = "$Id: ns_name.c,v 8.17 2001/10/03 14:34:32 marka Exp $"; #endif #include "port_before.h" @@ -30,13 +30,43 @@ static const char rcsid[] = "$Id: ns_name.c,v 8.15 2000/03/30 22:53:46 vixie Exp #include <resolv.h> #include <string.h> #include <ctype.h> +#include <stdlib.h> +#include <limits.h> #include "port_after.h" +#ifdef SPRINTF_CHAR +# define SPRINTF(x) strlen(sprintf/**/x) +#else +# define SPRINTF(x) ((size_t)sprintf x) +#endif + +#define NS_TYPE_ELT 0x40 /* EDNS0 extended label type */ +#define DNS_LABELTYPE_BITSTRING 0x41 + /* Data. */ static const char digits[] = "0123456789"; +static const char digitvalue[256] = { + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*16*/ + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*32*/ + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*48*/ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -1, -1, -1, -1, -1, /*64*/ + -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*80*/ + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*96*/ + -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*112*/ + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*128*/ + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*256*/ +}; + /* Forward. */ static int special(int); @@ -44,6 +74,10 @@ static int printable(int); static int dn_find(const u_char *, const u_char *, const u_char * const *, const u_char * const *); +static int encode_bitsring(const char **, const char *, + char **, char **, const char *); +static int labellen(const u_char *); +static int decode_bitstring(const char **, char *, const char *); /* Public. */ @@ -57,18 +91,20 @@ static int dn_find(const u_char *, const u_char *, * All other domains are returned in non absolute form */ int -ns_name_ntop(const u_char *src, char *dst, size_t dstsiz) { +ns_name_ntop(const u_char *src, char *dst, size_t dstsiz) +{ const u_char *cp; char *dn, *eom; u_char c; u_int n; + int l; cp = src; dn = dst; eom = dst + dstsiz; while ((n = *cp++) != 0) { - if ((n & NS_CMPRSFLGS) != 0) { + if ((n & NS_CMPRSFLGS) == NS_CMPRSFLGS) { /* Some kind of compression pointer. */ errno = EMSGSIZE; return (-1); @@ -80,11 +116,31 @@ ns_name_ntop(const u_char *src, char *dst, size_t dstsiz) { } *dn++ = '.'; } - if (dn + n >= eom) { + if ((l = labellen(cp - 1)) < 0) { + errno = EMSGSIZE; /* XXX */ + return(-1); + } + if (dn + l >= eom) { errno = EMSGSIZE; return (-1); } - for ((void)NULL; n > 0; n--) { + if ((n & NS_CMPRSFLGS) == NS_TYPE_ELT) { + int m; + + if (n != DNS_LABELTYPE_BITSTRING) { + /* XXX: labellen should reject this case */ + errno = EINVAL; + return(-1); + } + if ((m = decode_bitstring((const char **)&cp, dn, eom)) < 0) + { + errno = EMSGSIZE; + return(-1); + } + dn += m; + continue; + } + for ((void)NULL; l > 0; l--) { c = *cp++; if (special(c)) { if (dn + 1 >= eom) { @@ -138,9 +194,10 @@ ns_name_ntop(const u_char *src, char *dst, size_t dstsiz) { */ int -ns_name_pton(const char *src, u_char *dst, size_t dstsiz) { +ns_name_pton(const char *src, u_char *dst, size_t dstsiz) +{ u_char *label, *bp, *eom; - int c, n, escaped; + int c, n, escaped, e = 0; char *cp; escaped = 0; @@ -150,7 +207,31 @@ ns_name_pton(const char *src, u_char *dst, size_t dstsiz) { while ((c = *src++) != 0) { if (escaped) { - if ((cp = strchr(digits, c)) != NULL) { + if (c == '[') { /* start a bit string label */ + if ((cp = strchr(src, ']')) == NULL) { + errno = EINVAL; /* ??? */ + return(-1); + } + if ((e = encode_bitsring(&src, + cp + 2, + (char **)&label, + (char **)&bp, + (const char *)eom)) + != 0) { + errno = e; + return(-1); + } + escaped = 0; + label = bp++; + if ((c = *src++) == 0) + goto done; + else if (c != '.') { + errno = EINVAL; + return(-1); + } + continue; + } + else if ((cp = strchr(digits, c)) != NULL) { n = (cp - digits) * 100; if ((c = *src++) == 0 || (cp = strchr(digits, c)) == NULL) { @@ -218,6 +299,7 @@ ns_name_pton(const char *src, u_char *dst, size_t dstsiz) { errno = EMSGSIZE; return (-1); } + done: if (label >= eom) { errno = EMSGSIZE; return (-1); @@ -247,28 +329,34 @@ ns_name_pton(const char *src, u_char *dst, size_t dstsiz) { */ int -ns_name_ntol(const u_char *src, u_char *dst, size_t dstsiz) { +ns_name_ntol(const u_char *src, u_char *dst, size_t dstsiz) +{ const u_char *cp; u_char *dn, *eom; u_char c; u_int n; + int l; cp = src; dn = dst; eom = dst + dstsiz; while ((n = *cp++) != 0) { - if ((n & NS_CMPRSFLGS) != 0) { + if ((n & NS_CMPRSFLGS) == NS_CMPRSFLGS) { /* Some kind of compression pointer. */ errno = EMSGSIZE; return (-1); } *dn++ = n; - if (dn + n >= eom) { + if ((l = labellen(cp - 1)) < 0) { + errno = EMSGSIZE; + return (-1); + } + if (dn + l >= eom) { errno = EMSGSIZE; return (-1); } - for ((void)NULL; n > 0; n--) { + for ((void)NULL; l > 0; l--) { c = *cp++; if (isupper(c)) *dn++ = tolower(c); @@ -292,7 +380,7 @@ ns_name_unpack(const u_char *msg, const u_char *eom, const u_char *src, { const u_char *srcp, *dstlim; u_char *dstp; - int n, len, checked; + int n, len, checked, l; len = -1; checked = 0; @@ -308,16 +396,21 @@ ns_name_unpack(const u_char *msg, const u_char *eom, const u_char *src, /* Check for indirection. */ switch (n & NS_CMPRSFLGS) { case 0: + case NS_TYPE_ELT: /* Limit checks. */ - if (dstp + n + 1 >= dstlim || srcp + n >= eom) { + if ((l = labellen(srcp - 1)) < 0) { + errno = EMSGSIZE; + return(-1); + } + if (dstp + l + 1 >= dstlim || srcp + l >= eom) { errno = EMSGSIZE; return (-1); } - checked += n + 1; + checked += l + 1; *dstp++ = n; - memcpy(dstp, srcp, n); - dstp += n; - srcp += n; + memcpy(dstp, srcp, l); + dstp += l; + srcp += l; break; case NS_CMPRSFLGS: @@ -397,17 +490,23 @@ ns_name_pack(const u_char *src, u_char *dst, int dstsiz, /* make sure the domain we are about to add is legal */ l = 0; do { + int l0; + n = *srcp; - if ((n & NS_CMPRSFLGS) != 0) { + if ((n & NS_CMPRSFLGS) == NS_CMPRSFLGS) { errno = EMSGSIZE; return (-1); } - l += n + 1; + if ((l0 = labellen(srcp)) < 0) { + errno = EINVAL; + return(-1); + } + l += l0 + 1; if (l > MAXCDNAME) { errno = EMSGSIZE; return (-1); } - srcp += n + 1; + srcp += l0 + 1; } while (n != 0); /* from here on we need to reset compression pointer array on error */ @@ -435,9 +534,11 @@ ns_name_pack(const u_char *src, u_char *dst, int dstsiz, } } /* copy label to buffer */ - if (n & NS_CMPRSFLGS) { /* Should not happen. */ + if ((n & NS_CMPRSFLGS) == NS_CMPRSFLGS) { + /* Should not happen. */ goto cleanup; } + n = labellen(srcp); if (dstp + 1 + n >= eob) { goto cleanup; } @@ -527,9 +628,11 @@ ns_name_rollback(const u_char *src, const u_char **dnptrs, * 0 on success, -1 (with errno set) on failure. */ int -ns_name_skip(const u_char **ptrptr, const u_char *eom) { +ns_name_skip(const u_char **ptrptr, const u_char *eom) +{ const u_char *cp; u_int n; + int l; cp = *ptrptr; while (cp < eom && (n = *cp++) != 0) { @@ -538,6 +641,13 @@ ns_name_skip(const u_char **ptrptr, const u_char *eom) { case 0: /* normal case, n == len */ cp += n; continue; + case NS_TYPE_ELT: /* EDNS0 extended label */ + if ((l = labellen(cp - 1)) < 0) { + errno = EMSGSIZE; /* XXX */ + return(-1); + } + cp += l; + continue; case NS_CMPRSFLGS: /* indirection */ cp++; break; @@ -639,8 +749,11 @@ dn_find(const u_char *domain, const u_char *msg, */ switch (n & NS_CMPRSFLGS) { case 0: /* normal case, n == len */ + n = labellen(cp - 1); /* XXX */ + if (n != *dn++) goto next; + for ((void)NULL; n > 0; n--) if (mklower(*dn++) != mklower(*cp++)) @@ -651,7 +764,6 @@ dn_find(const u_char *domain, const u_char *msg, if (*dn) continue; goto next; - case NS_CMPRSFLGS: /* indirection */ cp = msg + (((n & 0x3f) << 8) | *cp); break; @@ -661,10 +773,169 @@ dn_find(const u_char *domain, const u_char *msg, return (-1); } } - next: + next: ; sp += *sp + 1; } } errno = ENOENT; return (-1); } + +static int +decode_bitstring(const char **cpp, char *dn, const char *eom) +{ + const char *cp = *cpp; + char *beg = dn, tc; + int b, blen, plen; + + if ((blen = (*cp & 0xff)) == 0) + blen = 256; + plen = (blen + 3) / 4; + plen += sizeof("\\[x/]") + (blen > 99 ? 3 : (blen > 9) ? 2 : 1); + if (dn + plen >= eom) + return(-1); + + cp++; + dn += SPRINTF((dn, "\\[x")); + for (b = blen; b > 7; b -= 8, cp++) + dn += SPRINTF((dn, "%02x", *cp & 0xff)); + if (b > 4) { + tc = *cp++; + dn += SPRINTF((dn, "%02x", tc & (0xff << (8 - b)))); + } else if (b > 0) { + tc = *cp++; + dn += SPRINTF((dn, "%1x", + ((tc >> 4) & 0x0f) & (0x0f << (4 - b)))); + } + dn += SPRINTF((dn, "/%d]", blen)); + + *cpp = cp; + return(dn - beg); +} + +static int +encode_bitsring(const char **bp, const char *end, char **labelp, + char ** dst, const char *eom) +{ + int afterslash = 0; + const char *cp = *bp; + char *tp, c; + const char *beg_blen; + char *end_blen = NULL; + int value = 0, count = 0, tbcount = 0, blen = 0; + + beg_blen = end_blen = NULL; + + /* a bitstring must contain at least 2 characters */ + if (end - cp < 2) + return(EINVAL); + + /* XXX: currently, only hex strings are supported */ + if (*cp++ != 'x') + return(EINVAL); + if (!isxdigit((*cp) & 0xff)) /* reject '\[x/BLEN]' */ + return(EINVAL); + + for (tp = *dst + 1; cp < end && tp < eom; cp++) { + switch((c = *cp)) { + case ']': /* end of the bitstring */ + if (afterslash) { + if (beg_blen == NULL) + return(EINVAL); + blen = (int)strtol(beg_blen, &end_blen, 10); + if (*end_blen != ']') + return(EINVAL); + } + if (count) + *tp++ = ((value << 4) & 0xff); + cp++; /* skip ']' */ + goto done; + case '/': + afterslash = 1; + break; + default: + if (afterslash) { + if (!isdigit(c&0xff)) + return(EINVAL); + if (beg_blen == NULL) { + + if (c == '0') { + /* blen never begings with 0 */ + return(EINVAL); + } + beg_blen = cp; + } + } else { + if (!isxdigit(c&0xff)) + return(EINVAL); + value <<= 4; + value += digitvalue[(int)c]; + count += 4; + tbcount += 4; + if (tbcount > 256) + return(EINVAL); + if (count == 8) { + *tp++ = value; + count = 0; + } + } + break; + } + } + done: + if (cp >= end || tp >= eom) + return(EMSGSIZE); + + /* + * bit length validation: + * If a <length> is present, the number of digits in the <bit-data> + * MUST be just sufficient to contain the number of bits specified + * by the <length>. If there are insignificant bits in a final + * hexadecimal or octal digit, they MUST be zero. + * RFC 2673, Section 3.2. + */ + if (blen > 0) { + int traillen; + + if (((blen + 3) & ~3) != tbcount) + return(EINVAL); + traillen = tbcount - blen; /* between 0 and 3 */ + if (((value << (8 - traillen)) & 0xff) != 0) + return(EINVAL); + } + else + blen = tbcount; + if (blen == 256) + blen = 0; + + /* encode the type and the significant bit fields */ + **labelp = DNS_LABELTYPE_BITSTRING; + **dst = blen; + + *bp = cp; + *dst = tp; + + return(0); +} + +static int +labellen(const u_char *lp) +{ + int bitlen; + u_char l = *lp; + + if ((l & NS_CMPRSFLGS) == NS_CMPRSFLGS) { + /* should be avoided by the caller */ + return(-1); + } + + if ((l & NS_CMPRSFLGS) == NS_TYPE_ELT) { + if (l == DNS_LABELTYPE_BITSTRING) { + if ((bitlen = *(lp + 1)) == 0) + bitlen = 256; + return((bitlen + 7 ) / 8 + 1); + } + return(-1); /* unknwon ELT */ + } + return(l); +} diff --git a/contrib/bind/lib/nameser/ns_parse.c b/contrib/bind/lib/nameser/ns_parse.c index 6858a91..f3f92c6 100644 --- a/contrib/bind/lib/nameser/ns_parse.c +++ b/contrib/bind/lib/nameser/ns_parse.c @@ -16,7 +16,7 @@ */ #ifndef lint -static const char rcsid[] = "$Id: ns_parse.c,v 8.15 2000/12/23 08:14:55 vixie Exp $"; +static const char rcsid[] = "$Id: ns_parse.c,v 8.17 2001/06/20 02:50:49 marka Exp $"; #endif /* Import. */ @@ -134,7 +134,7 @@ ns_parserr(ns_msg *handle, ns_sect section, int rrnum, ns_rr *rr) { int b; /* Make section right. */ - if (section < 0 || section >= ns_s_max) + if (section >= ns_s_max) RETERR(ENODEV); if (section != handle->_sect) setsection(handle, section); @@ -147,38 +147,38 @@ ns_parserr(ns_msg *handle, ns_sect section, int rrnum, ns_rr *rr) { if (rrnum < handle->_rrnum) setsection(handle, section); if (rrnum > handle->_rrnum) { - b = ns_skiprr(handle->_ptr, handle->_eom, section, + b = ns_skiprr(handle->_msg_ptr, handle->_eom, section, rrnum - handle->_rrnum); if (b < 0) return (-1); - handle->_ptr += b; + handle->_msg_ptr += b; handle->_rrnum = rrnum; } /* Do the parse. */ b = dn_expand(handle->_msg, handle->_eom, - handle->_ptr, rr->name, NS_MAXDNAME); + handle->_msg_ptr, rr->name, NS_MAXDNAME); if (b < 0) return (-1); - handle->_ptr += b; - if (handle->_ptr + NS_INT16SZ + NS_INT16SZ > handle->_eom) + handle->_msg_ptr += b; + if (handle->_msg_ptr + NS_INT16SZ + NS_INT16SZ > handle->_eom) RETERR(EMSGSIZE); - NS_GET16(rr->type, handle->_ptr); - NS_GET16(rr->rr_class, handle->_ptr); + NS_GET16(rr->type, handle->_msg_ptr); + NS_GET16(rr->rr_class, handle->_msg_ptr); if (section == ns_s_qd) { rr->ttl = 0; rr->rdlength = 0; rr->rdata = NULL; } else { - if (handle->_ptr + NS_INT32SZ + NS_INT16SZ > handle->_eom) + if (handle->_msg_ptr + NS_INT32SZ + NS_INT16SZ > handle->_eom) RETERR(EMSGSIZE); - NS_GET32(rr->ttl, handle->_ptr); - NS_GET16(rr->rdlength, handle->_ptr); - if (handle->_ptr + rr->rdlength > handle->_eom) + NS_GET32(rr->ttl, handle->_msg_ptr); + NS_GET16(rr->rdlength, handle->_msg_ptr); + if (handle->_msg_ptr + rr->rdlength > handle->_eom) RETERR(EMSGSIZE); - rr->rdata = handle->_ptr; - handle->_ptr += rr->rdlength; + rr->rdata = handle->_msg_ptr; + handle->_msg_ptr += rr->rdlength; } if (++handle->_rrnum > handle->_counts[(int)section]) setsection(handle, (ns_sect)((int)section + 1)); @@ -194,9 +194,9 @@ setsection(ns_msg *msg, ns_sect sect) { msg->_sect = sect; if (sect == ns_s_max) { msg->_rrnum = -1; - msg->_ptr = NULL; + msg->_msg_ptr = NULL; } else { msg->_rrnum = 0; - msg->_ptr = msg->_sections[(int)sect]; + msg->_msg_ptr = msg->_sections[(int)sect]; } } diff --git a/contrib/bind/lib/nameser/ns_print.c b/contrib/bind/lib/nameser/ns_print.c index 7348e1d..b23f805 100644 --- a/contrib/bind/lib/nameser/ns_print.c +++ b/contrib/bind/lib/nameser/ns_print.c @@ -16,7 +16,7 @@ */ #ifndef lint -static const char rcsid[] = "$Id: ns_print.c,v 8.22 2001/03/26 07:04:31 marka Exp $"; +static const char rcsid[] = "$Id: ns_print.c,v 8.24 2001/06/18 06:40:45 marka Exp $"; #endif /* Import. */ @@ -169,6 +169,7 @@ ns_sprintrrf(const u_char *msg, size_t msglen, case ns_t_mr: case ns_t_ns: case ns_t_ptr: + case ns_t_dname: T(addname(msg, msglen, &rdata, origin, &buf, &buflen)); break; @@ -571,8 +572,10 @@ ns_sprintrrf(const u_char *msg, size_t msglen, case ns_t_cert: { u_int c_type, key_tag, alg; - int n, siz; - char base64_cert[8192], *leader, tmp[40]; + int n; + unsigned int siz; + char base64_cert[8192], tmp[40]; + const char *leader; c_type = ns_get16(rdata); rdata += NS_INT16SZ; key_tag = ns_get16(rdata); rdata += NS_INT16SZ; @@ -582,7 +585,7 @@ ns_sprintrrf(const u_char *msg, size_t msglen, T(addstr(tmp, len, &buf, &buflen)); siz = (edata-rdata)*4/3 + 4; /* "+4" accounts for trailing \0 */ if (siz > sizeof(base64_cert) * 3/4) { - char *str = "record too long to print"; + const char *str = "record too long to print"; T(addstr(str, strlen(str), &buf, &buflen)); } else { @@ -656,6 +659,45 @@ ns_sprintrrf(const u_char *msg, size_t msglen, break; } + case ns_t_a6: { + struct in6_addr a; + int pbyte, pbit; + + /* prefix length */ + if (rdlen == 0) goto formerr; + len = SPRINTF((tmp, "%d ", *rdata)); + T(addstr(tmp, len, &buf, &buflen)); + pbit = *rdata; + if (pbit > 128) goto formerr; + pbyte = (pbit & ~7) / 8; + rdata++; + + /* address suffix: provided only when prefix len != 128 */ + if (pbit < 128) { + if (rdata + pbyte >= edata) goto formerr; + memset(&a, 0, sizeof(a)); + memcpy(&a.s6_addr[pbyte], rdata, sizeof(a) - pbyte); + (void) inet_ntop(AF_INET6, &a, buf, buflen); + addlen(strlen(buf), &buf, &buflen); + rdata += sizeof(a) - pbyte; + } + + /* prefix name: provided only when prefix len > 0 */ + if (pbit == 0) + break; + if (rdata >= edata) goto formerr; + T(addstr(" ", 1, &buf, &buflen)); + T(addname(msg, msglen, &rdata, origin, &buf, &buflen)); + + break; + } + + case ns_t_opt: { + len = SPRINTF((tmp, "%u bytes", class)); + T(addstr(tmp, len, &buf, &buflen)); + break; + } + default: comment = "unknown RR type"; goto hexify; @@ -667,7 +709,7 @@ ns_sprintrrf(const u_char *msg, size_t msglen, int n, m; char *p; - len = SPRINTF((tmp, "\\#(\t\t; %s", comment)); + len = SPRINTF((tmp, "\\# %u (\t; %s", edata - rdata, comment)); T(addstr(tmp, len, &buf, &buflen)); while (rdata < edata) { p = tmp; diff --git a/contrib/bind/lib/nameser/ns_sign.c b/contrib/bind/lib/nameser/ns_sign.c index 05a038a..d811411 100644 --- a/contrib/bind/lib/nameser/ns_sign.c +++ b/contrib/bind/lib/nameser/ns_sign.c @@ -16,7 +16,7 @@ */ #ifndef lint -static const char rcsid[] = "$Id: ns_sign.c,v 8.9 2000/12/23 08:14:57 vixie Exp $"; +static const char rcsid[] = "$Id: ns_sign.c,v 8.10 2001/05/29 05:49:39 marka Exp $"; #endif /* Import. */ @@ -233,7 +233,7 @@ ns_sign_tcp_init(void *k, const u_char *querysig, int querysiglen, state->key = k; if (state->key->dk_alg != KEY_HMAC_MD5) return (-ns_r_badkey); - if (querysiglen > sizeof(state->sig)) + if (querysiglen > (int)sizeof(state->sig)) return (-1); memcpy(state->sig, querysig, querysiglen); state->siglen = querysiglen; diff --git a/contrib/bind/lib/nameser/ns_verify.c b/contrib/bind/lib/nameser/ns_verify.c index 0f19913..9fd8782 100644 --- a/contrib/bind/lib/nameser/ns_verify.c +++ b/contrib/bind/lib/nameser/ns_verify.c @@ -16,7 +16,7 @@ */ #ifndef lint -static const char rcsid[] = "$Id: ns_verify.c,v 8.13 2000/03/29 15:55:00 bwelling Exp $"; +static const char rcsid[] = "$Id: ns_verify.c,v 8.14 2001/05/29 05:49:40 marka Exp $"; #endif /* Import. */ @@ -37,6 +37,7 @@ static const char rcsid[] = "$Id: ns_verify.c,v 8.13 2000/03/29 15:55:00 bwellin #include <stdio.h> #include <stdlib.h> #include <string.h> +#include <time.h> #include <unistd.h> #include <isc/dst.h> @@ -328,7 +329,7 @@ ns_verify_tcp_init(void *k, const u_char *querysig, int querysiglen, state->key = k; if (state->key->dk_alg != KEY_HMAC_MD5) return (-ns_r_badkey); - if (querysiglen > sizeof(state->sig)) + if (querysiglen > (int)sizeof(state->sig)) return (-1); memcpy(state->sig, querysig, querysiglen); state->siglen = querysiglen; @@ -341,7 +342,7 @@ ns_verify_tcp(u_char *msg, int *msglen, ns_tcp_tsig_state *state, { HEADER *hp = (HEADER *)msg; u_char *recstart, *rdatastart, *sigstart; - int sigfieldlen, otherfieldlen; + unsigned int sigfieldlen, otherfieldlen; u_char *cp, *eom = msg + *msglen, *cp2; char name[MAXDNAME], alg[MAXDNAME]; u_char buf[MAXDNAME]; diff --git a/contrib/bind/lib/resolv/Makefile b/contrib/bind/lib/resolv/Makefile index bfb49ec..3f98a20 100644 --- a/contrib/bind/lib/resolv/Makefile +++ b/contrib/bind/lib/resolv/Makefile @@ -13,7 +13,7 @@ # ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS # SOFTWARE. -# $Id: Makefile,v 8.35 2000/12/23 08:03:03 vixie Exp $ +# $Id: Makefile,v 8.36 2001/08/14 05:58:11 marka Exp $ # these are only appropriate for BSD 4.4 or derivatives, and are used in # development. normal builds will be done in the top level directory and @@ -63,7 +63,7 @@ ${LIBBIND}: ${OBJS} ${RANLIB} ${LIBBIND} .c.${O}: - if test ! -d ${THREADED} ; then mkdir ${THREADED} ; else true ; fi + mkdir ${THREADED} 2> /dev/null || test -d ${THREADED} -a -w ${THREADED} ${CC} ${CPPFLAGS} ${CFLAGS} ${BOUNDS} ${REENTRANT} -c $*.c \ -o ${THREADED}/$*.${O} -${LDS} ${LD} ${LD_LIBFLAGS} ${THREADED}/$*.${O} \ diff --git a/contrib/bind/lib/resolv/herror.c b/contrib/bind/lib/resolv/herror.c index bf4cce6..8265597 100644 --- a/contrib/bind/lib/resolv/herror.c +++ b/contrib/bind/lib/resolv/herror.c @@ -50,7 +50,7 @@ #if defined(LIBC_SCCS) && !defined(lint) static const char sccsid[] = "@(#)herror.c 8.1 (Berkeley) 6/4/93"; -static const char rcsid[] = "$Id: herror.c,v 8.11 1999/10/13 16:39:39 vixie Exp $"; +static const char rcsid[] = "$Id: herror.c,v 8.13 2001/06/18 14:44:06 marka Exp $"; #endif /* LIBC_SCCS and not lint */ #include "port_before.h" @@ -89,20 +89,24 @@ int h_errno; void herror(const char *s) { struct iovec iov[4], *v = iov; - extern int * __h_errno(); + char *t; if (s != NULL && *s != '\0') { - v->iov_base = (/*noconst*/ char *)s; - v->iov_len = strlen(s); + DE_CONST(s, t); + v->iov_base = t; + v->iov_len = strlen(t); v++; - v->iov_base = ": "; + DE_CONST(": ", t); + v->iov_base = t; v->iov_len = 2; v++; } - v->iov_base = (char *)hstrerror(*__h_errno()); + DE_CONST(hstrerror(*__h_errno()), t); + v->iov_base = t; v->iov_len = strlen(v->iov_base); v++; - v->iov_base = "\n"; + DE_CONST("\n", t); + v->iov_base = t; v->iov_len = 1; writev(STDERR_FILENO, iov, (v - iov) + 1); } diff --git a/contrib/bind/lib/resolv/res_debug.c b/contrib/bind/lib/resolv/res_debug.c index cff6473..9b61e11 100644 --- a/contrib/bind/lib/resolv/res_debug.c +++ b/contrib/bind/lib/resolv/res_debug.c @@ -95,7 +95,7 @@ #if defined(LIBC_SCCS) && !defined(lint) static const char sccsid[] = "@(#)res_debug.c 8.1 (Berkeley) 6/4/93"; -static const char rcsid[] = "$Id: res_debug.c,v 8.38 2001/02/13 23:12:56 marka Exp $"; +static const char rcsid[] = "$Id: res_debug.c,v 8.45 2001/12/19 12:05:56 marka Exp $"; #endif /* LIBC_SCCS and not lint */ #include "port_before.h" @@ -187,7 +187,12 @@ do_section(const res_state statp, ns_rr_name(rr), p_type(ns_rr_type(rr)), p_class(ns_rr_class(rr))); - else { + else if (section == ns_s_ar && ns_rr_type(rr) == ns_t_opt) { + u_int32_t ttl = ns_rr_ttl(rr); + fprintf(file, + "; EDNS: version: %u, udp=%u, flags=%04x\n", + (ttl>>16)&0xff, ns_rr_class(rr), ttl&0xffff); + } else { n = ns_sprintrr(handle, &rr, NULL, NULL, buf, buflen); if (n < 0) { @@ -356,32 +361,32 @@ p_fqname(const u_char *cp, const u_char *msg, FILE *file) { * C_ANY, but you can't have any records of that class in the database.) */ const struct res_sym __p_class_syms[] = { - {C_IN, "IN"}, - {C_CHAOS, "CHAOS"}, - {C_HS, "HS"}, - {C_HS, "HESIOD"}, - {C_ANY, "ANY"}, - {C_NONE, "NONE"}, - {C_IN, (char *)0} + {C_IN, "IN", (char *)0}, + {C_CHAOS, "CHAOS", (char *)0}, + {C_HS, "HS", (char *)0}, + {C_HS, "HESIOD", (char *)0}, + {C_ANY, "ANY", (char *)0}, + {C_NONE, "NONE", (char *)0}, + {C_IN, (char *)0, (char *)0} }; /* * Names of message sections. */ const struct res_sym __p_default_section_syms[] = { - {ns_s_qd, "QUERY"}, - {ns_s_an, "ANSWER"}, - {ns_s_ns, "AUTHORITY"}, - {ns_s_ar, "ADDITIONAL"}, - {0, (char *)0} + {ns_s_qd, "QUERY", (char *)0}, + {ns_s_an, "ANSWER", (char *)0}, + {ns_s_ns, "AUTHORITY", (char *)0}, + {ns_s_ar, "ADDITIONAL", (char *)0}, + {0, (char *)0, (char *)0} }; const struct res_sym __p_update_section_syms[] = { - {S_ZONE, "ZONE"}, - {S_PREREQ, "PREREQUISITE"}, - {S_UPDATE, "UPDATE"}, - {S_ADDT, "ADDITIONAL"}, - {0, (char *)0} + {S_ZONE, "ZONE", (char *)0}, + {S_PREREQ, "PREREQUISITE", (char *)0}, + {S_UPDATE, "UPDATE", (char *)0}, + {S_ADDT, "ADDITIONAL", (char *)0}, + {0, (char *)0, (char *)0} }; const struct res_sym __p_key_syms[] = { @@ -536,7 +541,17 @@ sym_ntop(const struct res_sym *syms, int number, int *success) { */ const char * p_type(int type) { - return (sym_ntos(__p_type_syms, type, (int *)0)); + int success; + const char *result; + static char typebuf[20]; + + result = sym_ntos(__p_type_syms, type, &success); + if (success) + return (result); + if (type < 0 || type > 0xfff) + return ("BADTYPE"); + sprintf(typebuf, "TYPE%d", type); + return (typebuf); } /* @@ -562,7 +577,17 @@ p_section(int section, int opcode) { */ const char * p_class(int class) { - return (sym_ntos(__p_class_syms, class, (int *)0)); + int success; + const char *result; + static char classbuf[20]; + + result = sym_ntos(__p_class_syms, class, &success); + if (success) + return (result); + if (class < 0 || class > 0xfff) + return ("BADCLASS"); + sprintf(classbuf, "CLASS%d", class); + return (classbuf); } /* @@ -585,6 +610,24 @@ p_option(u_long option) { case RES_DNSRCH: return "dnsrch"; case RES_INSECURE1: return "insecure1"; case RES_INSECURE2: return "insecure2"; + case RES_NOALIASES: return "noaliases"; + case RES_USE_INET6: return "inet6"; +#ifdef RES_USE_EDNS0 /* KAME extension */ + case RES_USE_EDNS0: return "edns0"; +#endif +#ifdef RES_USE_A6 + case RES_USE_A6: return "a6"; +#endif +#ifdef RES_USE_DNAME + case RES_USE_DNAME: return "dname"; +#endif +#ifdef RES_USE_DNSSEC + case RES_USE_DNSSEC: return "dnssec"; +#endif +#ifdef RES_NOTLDQUERY + case RES_NOTLDQUERY: return "no-tld-query"; +#endif + /* XXX nonreentrant */ default: sprintf(nbuf, "?0x%lx?", (u_long)option); return (nbuf); @@ -651,14 +694,14 @@ precsize_aton(strptr) cp = *strptr; - while (isdigit(*cp)) + while (isdigit((unsigned char)*cp)) mval = mval * 10 + (*cp++ - '0'); if (*cp == '.') { /* centimeters */ cp++; - if (isdigit(*cp)) { + if (isdigit((unsigned char)*cp)) { cmval = (*cp++ - '0') * 10; - if (isdigit(*cp)) { + if (isdigit((unsigned char)*cp)) { cmval += (*cp++ - '0'); } } @@ -692,44 +735,44 @@ latlon2ul(latlonstrptr,which) cp = *latlonstrptr; - while (isdigit(*cp)) + while (isdigit((unsigned char)*cp)) deg = deg * 10 + (*cp++ - '0'); - while (isspace(*cp)) + while (isspace((unsigned char)*cp)) cp++; - if (!(isdigit(*cp))) + if (!(isdigit((unsigned char)*cp))) goto fndhemi; - while (isdigit(*cp)) + while (isdigit((unsigned char)*cp)) min = min * 10 + (*cp++ - '0'); - while (isspace(*cp)) + while (isspace((unsigned char)*cp)) cp++; - if (!(isdigit(*cp))) + if (!(isdigit((unsigned char)*cp))) goto fndhemi; - while (isdigit(*cp)) + while (isdigit((unsigned char)*cp)) secs = secs * 10 + (*cp++ - '0'); if (*cp == '.') { /* decimal seconds */ cp++; - if (isdigit(*cp)) { + if (isdigit((unsigned char)*cp)) { secsfrac = (*cp++ - '0') * 100; - if (isdigit(*cp)) { + if (isdigit((unsigned char)*cp)) { secsfrac += (*cp++ - '0') * 10; - if (isdigit(*cp)) { + if (isdigit((unsigned char)*cp)) { secsfrac += (*cp++ - '0'); } } } } - while (!isspace(*cp)) /* if any trailing garbage */ + while (!isspace((unsigned char)*cp)) /* if any trailing garbage */ cp++; - while (isspace(*cp)) + while (isspace((unsigned char)*cp)) cp++; fndhemi: @@ -767,10 +810,10 @@ latlon2ul(latlonstrptr,which) cp++; /* skip the hemisphere */ - while (!isspace(*cp)) /* if any trailing garbage */ + while (!isspace((unsigned char)*cp)) /* if any trailing garbage */ cp++; - while (isspace(*cp)) /* move to next field */ + while (isspace((unsigned char)*cp)) /* move to next field */ cp++; *latlonstrptr = cp; @@ -828,14 +871,14 @@ loc_aton(ascii, binary) if (*cp == '+') cp++; - while (isdigit(*cp)) + while (isdigit((unsigned char)*cp)) altmeters = altmeters * 10 + (*cp++ - '0'); if (*cp == '.') { /* decimal meters */ cp++; - if (isdigit(*cp)) { + if (isdigit((unsigned char)*cp)) { altfrac = (*cp++ - '0') * 10; - if (isdigit(*cp)) { + if (isdigit((unsigned char)*cp)) { altfrac += (*cp++ - '0'); } } @@ -843,10 +886,10 @@ loc_aton(ascii, binary) alt = (10000000 + (altsign * (altmeters * 100 + altfrac))); - while (!isspace(*cp) && (cp < maxcp)) /* if trailing garbage or m */ + while (!isspace((unsigned char)*cp) && (cp < maxcp)) /* if trailing garbage or m */ cp++; - while (isspace(*cp) && (cp < maxcp)) + while (isspace((unsigned char)*cp) && (cp < maxcp)) cp++; if (cp >= maxcp) @@ -854,10 +897,10 @@ loc_aton(ascii, binary) siz = precsize_aton(&cp); - while (!isspace(*cp) && (cp < maxcp)) /* if trailing garbage or m */ + while (!isspace((unsigned char)*cp) && (cp < maxcp)) /* if trailing garbage or m */ cp++; - while (isspace(*cp) && (cp < maxcp)) + while (isspace((unsigned char)*cp) && (cp < maxcp)) cp++; if (cp >= maxcp) @@ -865,10 +908,10 @@ loc_aton(ascii, binary) hp = precsize_aton(&cp); - while (!isspace(*cp) && (cp < maxcp)) /* if trailing garbage or m */ + while (!isspace((unsigned char)*cp) && (cp < maxcp)) /* if trailing garbage or m */ cp++; - while (isspace(*cp) && (cp < maxcp)) + while (isspace((unsigned char)*cp) && (cp < maxcp)) cp++; if (cp >= maxcp) @@ -896,14 +939,15 @@ loc_ntoa(binary, ascii) const u_char *binary; char *ascii; { - static char *error = "?"; + static const char *error = "?"; static char tmpbuf[sizeof "1000 60 60.000 N 1000 60 60.000 W -12345678.00m 90000000.00m 90000000.00m 90000000.00m"]; const u_char *cp = binary; int latdeg, latmin, latsec, latsecfrac; int longdeg, longmin, longsec, longsecfrac; - char northsouth, eastwest, *altsign; + char northsouth, eastwest; + const char *altsign; int altmeters, altfrac; const u_int32_t referencealt = 100000 * 100; @@ -975,24 +1019,24 @@ loc_ntoa(binary, ascii) altfrac = altval % 100; altmeters = (altval / 100); - if ((sizestr = strdup(precsize_ntoa(sizeval))) == NULL) - sizestr = error; - if ((hpstr = strdup(precsize_ntoa(hpval))) == NULL) - hpstr = error; - if ((vpstr = strdup(precsize_ntoa(vpval))) == NULL) - vpstr = error; + sizestr = strdup(precsize_ntoa(sizeval)); + hpstr = strdup(precsize_ntoa(hpval)); + vpstr = strdup(precsize_ntoa(vpval)); sprintf(ascii, "%d %.2d %.2d.%.3d %c %d %.2d %.2d.%.3d %c %s%d.%.2dm %sm %sm %sm", latdeg, latmin, latsec, latsecfrac, northsouth, longdeg, longmin, longsec, longsecfrac, eastwest, - altsign, altmeters, altfrac, sizestr, hpstr, vpstr); + altsign, altmeters, altfrac, + (sizestr != NULL) ? sizestr : error, + (hpstr != NULL) ? hpstr : error, + (vpstr != NULL) ? vpstr : error); - if (sizestr != error) + if (sizestr != NULL) free(sizestr); - if (hpstr != error) + if (hpstr != NULL) free(hpstr); - if (vpstr != error) + if (vpstr != NULL) free(vpstr); return (ascii); @@ -1048,3 +1092,47 @@ p_secstodate (u_long secs) { time->tm_hour, time->tm_min, time->tm_sec); return (output); } + +u_int16_t +res_nametoclass(const char *buf, int *successp) { + unsigned long result; + char *endptr; + int success; + + result = sym_ston(__p_class_syms, buf, &success); + if (success) + goto done; + + if (strncasecmp(buf, "CLASS", 5) != 0 || + !isdigit((unsigned char)buf[5])) + goto done; + result = strtoul(buf + 5, &endptr, 10); + if (*endptr == '\0' && result <= 0xffff) + success = 1; + done: + if (successp) + *successp = success; + return (result); +} + +u_int16_t +res_nametotype(const char *buf, int *successp) { + unsigned long result; + char *endptr; + int success; + + result = sym_ston(__p_type_syms, buf, &success); + if (success) + goto done; + + if (strncasecmp(buf, "type", 4) != 0 || + !isdigit((unsigned char)buf[4])) + goto done; + result = strtoul(buf + 4, &endptr, 10); + if (*endptr == '\0' && result <= 0xffff) + success = 1; + done: + if (successp) + *successp = success; + return (result); +} diff --git a/contrib/bind/lib/resolv/res_findzonecut.c b/contrib/bind/lib/resolv/res_findzonecut.c index 2e8df2c..02a28da 100644 --- a/contrib/bind/lib/resolv/res_findzonecut.c +++ b/contrib/bind/lib/resolv/res_findzonecut.c @@ -1,5 +1,5 @@ #if !defined(lint) && !defined(SABER) -static const char rcsid[] = "$Id: res_findzonecut.c,v 8.12 2000/11/22 01:20:44 marka Exp $"; +static const char rcsid[] = "$Id: res_findzonecut.c,v 8.15 2001/11/01 05:21:22 marka Exp $"; #endif /* not lint */ /* @@ -78,13 +78,13 @@ static void free_nsrr(rrset_ns *, rr_ns *); static rr_ns * find_ns(rrset_ns *, const char *); static int do_query(res_state, const char *, ns_class, ns_type, u_char *, ns_msg *); -static void dprintf(const char *, ...); +static void res_dprintf(const char *, ...) ISC_FORMAT_PRINTF(1, 2); /* Macros. */ #define DPRINTF(x) do {\ int save_errno = errno; \ - if ((statp->options & RES_DEBUG) != 0) dprintf x; \ + if ((statp->options & RES_DEBUG) != 0) res_dprintf x; \ errno = save_errno; \ } while (0) @@ -527,12 +527,14 @@ free_nsrrset(rrset_ns *nsrrsp) { static void free_nsrr(rrset_ns *nsrrsp, rr_ns *nsrr) { rr_a *arr; + char *tmp; while ((arr = HEAD(nsrr->addrs)) != NULL) { UNLINK(nsrr->addrs, arr, link); free(arr); } - free((char *)nsrr->name); + DE_CONST(nsrr->name, tmp); + free(tmp); UNLINK(*nsrrsp, nsrr, link); free(nsrr); } @@ -590,7 +592,7 @@ do_query(res_state statp, const char *dname, ns_class class, ns_type qtype, } static void -dprintf(const char *fmt, ...) { +res_dprintf(const char *fmt, ...) { va_list ap; va_start(ap, fmt); diff --git a/contrib/bind/lib/resolv/res_init.c b/contrib/bind/lib/resolv/res_init.c index 8c63351..8dc72f4 100644 --- a/contrib/bind/lib/resolv/res_init.c +++ b/contrib/bind/lib/resolv/res_init.c @@ -70,7 +70,7 @@ #if defined(LIBC_SCCS) && !defined(lint) static const char sccsid[] = "@(#)res_init.c 8.1 (Berkeley) 6/7/93"; -static const char rcsid[] = "$Id: res_init.c,v 8.19 2001/03/08 03:57:16 marka Exp $"; +static const char rcsid[] = "$Id: res_init.c,v 8.28 2002/01/30 01:07:35 marka Exp $"; #endif /* LIBC_SCCS and not lint */ #include "port_before.h" @@ -85,14 +85,19 @@ static const char rcsid[] = "$Id: res_init.c,v 8.19 2001/03/08 03:57:16 marka Ex #include <arpa/nameser.h> #include <ctype.h> -#include <resolv.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> +#include <netdb.h> #include "port_after.h" +/* ensure that sockaddr_in6 and IN6ADDR_ANY_INIT are declared / defined */ +#include <resolv.h> + +#include "res_private.h" + /* Options. Should all be left alone. */ #define RESOLVSORT #define DEBUG @@ -164,6 +169,9 @@ __res_vinit(res_state statp, int preinit) { statp->id = res_randomid(); } + if ((statp->options & RES_INIT) != 0) + res_ndestroy(statp); + #ifdef USELOOPBACK statp->nsaddr.sin_addr = inet_makeaddr(IN_LOOPBACKNET, 1); #else @@ -171,6 +179,9 @@ __res_vinit(res_state statp, int preinit) { #endif statp->nsaddr.sin_family = AF_INET; statp->nsaddr.sin_port = htons(NAMESERVER_PORT); +#ifdef HAVE_SA_LEN + statp->nsaddr.sin_len = sizeof(struct sockaddr_in); +#endif statp->nscount = 1; statp->ndots = 1; statp->pfcode = 0; @@ -179,6 +190,13 @@ __res_vinit(res_state statp, int preinit) { statp->qhook = NULL; statp->rhook = NULL; statp->_u._ext.nscount = 0; + statp->_u._ext.ext = malloc(sizeof(*statp->_u._ext.ext)); + if (statp->_u._ext.ext != NULL) { + memset(statp->_u._ext.ext, 0, sizeof(*statp->_u._ext.ext)); + statp->_u._ext.ext->nsaddrs[0].sin = statp->nsaddr; + strcpy(statp->_u._ext.ext->nsuffix, "ip6.int"); + strcpy(statp->_u._ext.ext->bsuffix, "ip6.arpa"); + } #ifdef RESOLVSORT statp->nsort = 0; #endif @@ -284,17 +302,36 @@ __res_vinit(res_state statp, int preinit) { } /* read nameservers to query */ if (MATCH(buf, "nameserver") && nserv < MAXNS) { - struct in_addr a; + struct addrinfo hints, *ai; + char sbuf[NI_MAXSERV]; + const size_t minsiz = + sizeof(statp->_u._ext.ext->nsaddrs[0]); cp = buf + sizeof("nameserver") - 1; while (*cp == ' ' || *cp == '\t') cp++; - if ((*cp != '\0') && (*cp != '\n') && inet_aton(cp, &a)) { - statp->nsaddr_list[nserv].sin_addr = a; - statp->nsaddr_list[nserv].sin_family = AF_INET; - statp->nsaddr_list[nserv].sin_port = - htons(NAMESERVER_PORT); - nserv++; + cp[strcspn(cp, ";# \t\n")] = '\0'; + if ((*cp != '\0') && (*cp != '\n')) { + memset(&hints, 0, sizeof(hints)); + hints.ai_family = PF_UNSPEC; + hints.ai_socktype = SOCK_DGRAM; /*dummy*/ + hints.ai_flags = AI_NUMERICHOST; + sprintf(sbuf, "%u", NAMESERVER_PORT); + if (getaddrinfo(cp, sbuf, &hints, &ai) == 0 && + ai->ai_addrlen <= minsiz) { + if (statp->_u._ext.ext != NULL) { + memcpy(&statp->_u._ext.ext->nsaddrs[nserv], + ai->ai_addr, ai->ai_addrlen); + } + if (ai->ai_addrlen <= + sizeof(statp->nsaddr_list[nserv])) { + memcpy(&statp->nsaddr_list[nserv], + ai->ai_addr, ai->ai_addrlen); + } else + statp->nsaddr_list[nserv].sin_family = 0; + freeaddrinfo(ai); + nserv++; + } } continue; } @@ -310,7 +347,7 @@ __res_vinit(res_state statp, int preinit) { break; net = cp; while (*cp && !ISSORTMASK(*cp) && *cp != ';' && - isascii(*cp) && !isspace(*cp)) + isascii(*cp) && !isspace((unsigned char)*cp)) cp++; n = *cp; *cp = 0; @@ -320,7 +357,8 @@ __res_vinit(res_state statp, int preinit) { *cp++ = n; net = cp; while (*cp && *cp != ';' && - isascii(*cp) && !isspace(*cp)) + isascii(*cp) && + !isspace((unsigned char)*cp)) cp++; n = *cp; *cp = 0; @@ -346,8 +384,7 @@ __res_vinit(res_state statp, int preinit) { continue; } } - - if (nserv > 1) + if (nserv > 1) statp->nscount = nserv; #ifdef RESOLVSORT statp->nsort = nsort; @@ -404,9 +441,11 @@ __res_vinit(res_state statp, int preinit) { } static void -res_setoptions(res_state statp, const char *options, const char *source) { +res_setoptions(res_state statp, const char *options, const char *source) +{ const char *cp = options; int i; + struct __res_state_ext *ext = statp->_u._ext.ext; #ifdef DEBUG if (statp->options & RES_DEBUG) @@ -449,6 +488,11 @@ res_setoptions(res_state statp, const char *options, const char *source) { } printf(";;\tdebug\n"); #endif + } else if (!strncmp(cp, "no_tld_query", + sizeof("no_tld_query") - 1) || + !strncmp(cp, "no-tld-query", + sizeof("no-tld-query") - 1)) { + statp->options |= RES_NOTLDQUERY; } else if (!strncmp(cp, "inet6", sizeof("inet6") - 1)) { statp->options |= RES_USE_INET6; } else if (!strncmp(cp, "rotate", sizeof("rotate") - 1)) { @@ -456,9 +500,52 @@ res_setoptions(res_state statp, const char *options, const char *source) { } else if (!strncmp(cp, "no-check-names", sizeof("no-check-names") - 1)) { statp->options |= RES_NOCHECKNAME; - } else { + } +#ifdef RES_USE_EDNS0 + else if (!strncmp(cp, "edns0", sizeof("edns0") - 1)) { + statp->options |= RES_USE_EDNS0; + } +#endif + else if (!strncmp(cp, "a6", sizeof("a6") - 1)) { + statp->options |= RES_USE_A6; + } + else if (!strncmp(cp, "dname", sizeof("dname") - 1)) { + statp->options |= RES_USE_DNAME; + } + else if (!strncmp(cp, "nibble:", sizeof("nibble:") - 1)) { + if (ext == NULL) + goto skip; + cp += sizeof("nibble:") - 1; + i = MIN(strcspn(cp, " \t"), sizeof(ext->nsuffix) - 1); + strncpy(ext->nsuffix, cp, i); + ext->nsuffix[i] = '\0'; + } + else if (!strncmp(cp, "bitstring:", sizeof("bitstring:") - 1)) { + if (ext == NULL) + goto skip; + cp += sizeof("bitstring:") - 1; + i = MIN(strcspn(cp, " \t"), sizeof(ext->bsuffix) - 1); + strncpy(ext->bsuffix, cp, i); + ext->bsuffix[i] = '\0'; + } + else if (!strncmp(cp, "v6revmode:", sizeof("v6revmode:") - 1)) { + cp += sizeof("v6revmode:") - 1; + if (!strncmp(cp, "nibble", sizeof("nibble") - 1)) { + statp->options &= ~RES_NO_NIBBLE; + statp->options |= RES_NO_BITSTRING; + } else if (!strncmp(cp, "bitstring", + sizeof("bitstring") - 1)) { + statp->options |= RES_NO_NIBBLE; + statp->options &= ~RES_NO_BITSTRING; + } else if (!strncmp(cp, "both", sizeof("both") - 1)) { + statp->options &= + ~(RES_NO_NIBBLE|RES_NO_BITSTRING); + } + } + else { /* XXX - print a warning here? */ } + skip: /* skip to next run of spaces */ while (*cp && *cp != ' ' && *cp != '\t') cp++; @@ -512,3 +599,123 @@ res_nclose(res_state statp) { } } } + +void +res_ndestroy(res_state statp) { + res_nclose(statp); + if (statp->_u._ext.ext != NULL) + free(statp->_u._ext.ext); + statp->options &= ~RES_INIT; + statp->_u._ext.ext = NULL; +} + +const char * +res_get_nibblesuffix(res_state statp) { + if (statp->_u._ext.ext) + return (statp->_u._ext.ext->nsuffix); + return ("ip6.int"); +} + +const char * +res_get_bitstringsuffix(res_state statp) { + if (statp->_u._ext.ext) + return (statp->_u._ext.ext->bsuffix); + return ("ip6.arpa"); +} + +void +res_setservers(res_state statp, const union res_sockaddr_union *set, int cnt) { + int i, nserv; + size_t size; + + /* close open servers */ + res_nclose(statp); + + /* cause rtt times to be forgotten */ + statp->_u._ext.nscount = 0; + + nserv = 0; + for (i = 0; i < cnt && nserv < MAXNS; i++) { + switch (set->sin.sin_family) { + case AF_INET: + size = sizeof(set->sin); + if (statp->_u._ext.ext) + memcpy(&statp->_u._ext.ext->nsaddrs[nserv], + &set->sin, size); + if (size <= sizeof(statp->nsaddr_list[nserv])) + memcpy(&statp->nsaddr_list[nserv], + &set->sin, size); + else + statp->nsaddr_list[nserv].sin_family = 0; + nserv++; + break; + +#ifdef HAS_INET6_STRUCTS + case AF_INET6: + size = sizeof(set->sin6); + if (statp->_u._ext.ext) + memcpy(&statp->_u._ext.ext->nsaddrs[nserv], + &set->sin6, size); + if (size <= sizeof(statp->nsaddr_list[nserv])) + memcpy(&statp->nsaddr_list[nserv], + &set->sin6, size); + else + statp->nsaddr_list[nserv].sin_family = 0; + nserv++; + break; +#endif + + default: + break; + } + set++; + } + statp->nscount = nserv; + +} + +int +res_getservers(res_state statp, union res_sockaddr_union *set, int cnt) { + int i; + size_t size; + u_int16_t family; + + for (i = 0; i < statp->nscount && i < cnt; i++) { + if (statp->_u._ext.ext) + family = statp->_u._ext.ext->nsaddrs[i].sin.sin_family; + else + family = statp->nsaddr_list[i].sin_family; + + switch (family) { + case AF_INET: + size = sizeof(set->sin); + if (statp->_u._ext.ext) + memcpy(&set->sin, + &statp->_u._ext.ext->nsaddrs[i], + size); + else + memcpy(&set->sin, &statp->nsaddr_list[i], + size); + break; + +#ifdef HAS_INET6_STRUCTS + case AF_INET6: + size = sizeof(set->sin6); + if (statp->_u._ext.ext) + memcpy(&set->sin6, + &statp->_u._ext.ext->nsaddrs[i], + size); + else + memcpy(&set->sin6, &statp->nsaddr_list[i], + size); + break; +#endif + + default: + set->sin.sin_family = 0; + break; + } + set++; + } + return (statp->nscount); +} diff --git a/contrib/bind/lib/resolv/res_mkquery.c b/contrib/bind/lib/resolv/res_mkquery.c index 17b1ccf..7041227 100644 --- a/contrib/bind/lib/resolv/res_mkquery.c +++ b/contrib/bind/lib/resolv/res_mkquery.c @@ -70,7 +70,7 @@ #if defined(LIBC_SCCS) && !defined(lint) static const char sccsid[] = "@(#)res_mkquery.c 8.1 (Berkeley) 6/4/93"; -static const char rcsid[] = "$Id: res_mkquery.c,v 8.12 1999/10/13 16:39:40 vixie Exp $"; +static const char rcsid[] = "$Id: res_mkquery.c,v 8.14 2001/09/24 13:50:27 marka Exp $"; #endif /* LIBC_SCCS and not lint */ #include "port_before.h" @@ -109,6 +109,8 @@ res_nmkquery(res_state statp, register int n; u_char *dnptrs[20], **dpp, **lastdnptr; + UNUSED(newrr_in); + #ifdef DEBUG if (statp->options & RES_DEBUG) printf(";; res_nmkquery(%s, %s, %s, %s)\n", @@ -154,7 +156,7 @@ res_nmkquery(res_state statp, * Make an additional record for completion domain. */ buflen -= RRFIXEDSZ; - n = dn_comp((char *)data, cp, buflen, dnptrs, lastdnptr); + n = dn_comp((const char *)data, cp, buflen, dnptrs, lastdnptr); if (n < 0) return (-1); cp += n; @@ -197,3 +199,60 @@ res_nmkquery(res_state statp, } return (cp - buf); } + +#ifdef RES_USE_EDNS0 +/* attach OPT pseudo-RR, as documented in RFC2671 (EDNS0). */ +#ifndef T_OPT +#define T_OPT 41 +#endif + +int +res_nopt(statp, n0, buf, buflen, anslen) + res_state statp; + int n0; + u_char *buf; /* buffer to put query */ + int buflen; /* size of buffer */ + int anslen; /* answer buffer length */ +{ + register HEADER *hp; + register u_char *cp; + u_int16_t flags = 0; + +#ifdef DEBUG + if ((statp->options & RES_DEBUG) != 0) + printf(";; res_nopt()\n"); +#endif + + hp = (HEADER *) buf; + cp = buf + n0; + buflen -= n0; + + if (buflen < 1 + RRFIXEDSZ) + return -1; + + *cp++ = 0; /* "." */ + buflen--; + + __putshort(T_OPT, cp); /* TYPE */ + cp += INT16SZ; + __putshort(anslen & 0xffff, cp); /* CLASS = UDP payload size */ + cp += INT16SZ; + *cp++ = NOERROR; /* extended RCODE */ + *cp++ = 0; /* EDNS version */ + if (statp->options & RES_USE_DNSSEC) { +#ifdef DEBUG + if (statp->options & RES_DEBUG) + printf(";; res_opt()... ENDS0 DNSSEC\n"); +#endif + flags |= NS_OPT_DNSSEC_OK; + } + __putshort(flags, cp); + cp += INT16SZ; + __putshort(0, cp); /* RDLEN */ + cp += INT16SZ; + hp->arcount = htons(ntohs(hp->arcount) + 1); + buflen -= RRFIXEDSZ; + + return cp - buf; +} +#endif diff --git a/contrib/bind/lib/resolv/res_mkupdate.c b/contrib/bind/lib/resolv/res_mkupdate.c index ecf66dd..6071360 100644 --- a/contrib/bind/lib/resolv/res_mkupdate.c +++ b/contrib/bind/lib/resolv/res_mkupdate.c @@ -21,7 +21,7 @@ */ #if !defined(lint) && !defined(SABER) -static const char rcsid[] = "$Id: res_mkupdate.c,v 1.25 2000/11/22 01:20:46 marka Exp $"; +static const char rcsid[] = "$Id: res_mkupdate.c,v 1.26 2001/05/29 05:49:47 marka Exp $"; #endif /* not lint */ #include "port_before.h" @@ -328,7 +328,7 @@ res_nmkupdate(res_state statp, ns_updrec *rrecp_in, u_char *buf, int buflen) { break; case T_WKS: { char bm[MAXPORT/8]; - int maxbm = 0; + unsigned int maxbm = 0; if (!getword_str(buf2, sizeof buf2, &startp, endp)) return (-1); @@ -890,7 +890,7 @@ struct valuelist { }; static struct valuelist *servicelist, *protolist; -void +static void res_buildservicelist() { struct servent *sp; struct valuelist *slp; @@ -936,7 +936,7 @@ res_destroyservicelist() { } void -res_buildprotolist() { +res_buildprotolist(void) { struct protoent *pp; struct valuelist *slp; @@ -965,7 +965,7 @@ res_buildprotolist() { } void -res_destroyprotolist() { +res_destroyprotolist(void) { struct valuelist *plp, *plp_next; for (plp = protolist; plp != NULL; plp = plp_next) { diff --git a/contrib/bind/lib/resolv/res_private.h b/contrib/bind/lib/resolv/res_private.h new file mode 100644 index 0000000..2c7fa5e --- /dev/null +++ b/contrib/bind/lib/resolv/res_private.h @@ -0,0 +1,20 @@ +#ifndef res_private_h +#define res_private_h + +struct __res_state_ext { + union res_sockaddr_union nsaddrs[MAXNS]; + struct sort_list { + int af; + union { + struct in_addr ina; + struct in6_addr in6a; + } addr, mask; + } sort_list[MAXRESOLVSORT]; + char nsuffix[64]; + char bsuffix[64]; +}; + +extern int +res_ourserver_p(const res_state statp, const struct sockaddr *sa); + +#endif diff --git a/contrib/bind/lib/resolv/res_query.c b/contrib/bind/lib/resolv/res_query.c index 3147f1e..61f5df9 100644 --- a/contrib/bind/lib/resolv/res_query.c +++ b/contrib/bind/lib/resolv/res_query.c @@ -70,7 +70,7 @@ #if defined(LIBC_SCCS) && !defined(lint) static const char sccsid[] = "@(#)res_query.c 8.1 (Berkeley) 6/4/93"; -static const char rcsid[] = "$Id: res_query.c,v 8.20 2000/02/29 05:39:12 vixie Exp $"; +static const char rcsid[] = "$Id: res_query.c,v 8.23 2001/09/24 13:50:29 marka Exp $"; #endif /* LIBC_SCCS and not lint */ #include "port_before.h" @@ -117,7 +117,11 @@ res_nquery(res_state statp, u_char buf[MAXPACKET]; HEADER *hp = (HEADER *) answer; int n; + u_int oflags; + oflags = statp->_flags; + +again: hp->rcode = NOERROR; /* default */ #ifdef DEBUG @@ -127,6 +131,11 @@ res_nquery(res_state statp, n = res_nmkquery(statp, QUERY, name, class, type, NULL, 0, NULL, buf, sizeof(buf)); +#ifdef RES_USE_EDNS0 + if (n > 0 && (statp->_flags & RES_F_EDNS0ERR) == 0 && + (statp->options & (RES_USE_EDNS0|RES_USE_DNSSEC)) != 0) + n = res_nopt(statp, n, buf, sizeof(buf), anslen); +#endif if (n <= 0) { #ifdef DEBUG if (statp->options & RES_DEBUG) @@ -137,6 +146,16 @@ res_nquery(res_state statp, } n = res_nsend(statp, buf, n, answer, anslen); if (n < 0) { +#ifdef RES_USE_EDNS0 + /* if the query choked with EDNS0, retry without EDNS0 */ + if ((statp->options & (RES_USE_EDNS0|RES_USE_DNSSEC)) != 0 && + ((oflags ^ statp->_flags) & RES_F_EDNS0ERR) != 0) { + statp->_flags |= RES_F_EDNS0ERR; + if (statp->options & RES_DEBUG) + printf(";; res_nquery: retry without EDNS0\n"); + goto again; + } +#endif #ifdef DEBUG if (statp->options & RES_DEBUG) printf(";; res_query: send error\n"); @@ -193,6 +212,7 @@ res_nsearch(res_state statp, int trailing_dot, ret, saved_herrno; int got_nodata = 0, got_servfail = 0, root_on_list = 0; int tried_as_is = 0; + int searched = 0; errno = 0; RES_SET_H_ERRNO(statp, HOST_NOT_FOUND); /* True if we never query. */ @@ -236,6 +256,7 @@ res_nsearch(res_state statp, for (domain = (const char * const *)statp->dnsrch; *domain && !done; domain++) { + searched = 1; if (domain[0][0] == '\0' || (domain[0][0] == '.' && domain[0][1] == '\0')) @@ -293,11 +314,11 @@ res_nsearch(res_state statp, } /* - * If the name has any dots at all, and no earlier 'as-is' query - * for the name, and "." is not on the search list, then try an as-is - * query now. + * If the query has not already been tried as is then try it + * unless RES_NOTLDQUERY is set and there were no dots. */ - if (statp->ndots && !(tried_as_is || root_on_list)) { + if ((dots || !searched || (statp->options & RES_NOTLDQUERY) == 0) && + !(tried_as_is || root_on_list)) { ret = res_nquerydomain(statp, name, NULL, class, type, answer, anslen); if (ret > 0) @@ -383,17 +404,18 @@ res_hostalias(const res_state statp, const char *name, char *dst, size_t siz) { setbuf(fp, NULL); buf[sizeof(buf) - 1] = '\0'; while (fgets(buf, sizeof(buf), fp)) { - for (cp1 = buf; *cp1 && !isspace(*cp1); ++cp1) + for (cp1 = buf; *cp1 && !isspace((unsigned char)*cp1); ++cp1) ; if (!*cp1) break; *cp1 = '\0'; if (ns_samename(buf, name) == 1) { - while (isspace(*++cp1)) + while (isspace((unsigned char)*++cp1)) ; if (!*cp1) break; - for (cp2 = cp1 + 1; *cp2 && !isspace(*cp2); ++cp2) + for (cp2 = cp1 + 1; *cp2 && + !isspace((unsigned char)*cp2); ++cp2) ; *cp2 = '\0'; strncpy(dst, cp1, siz - 1); diff --git a/contrib/bind/lib/resolv/res_send.c b/contrib/bind/lib/resolv/res_send.c index ade9eac..6dfea59 100644 --- a/contrib/bind/lib/resolv/res_send.c +++ b/contrib/bind/lib/resolv/res_send.c @@ -70,7 +70,7 @@ #if defined(LIBC_SCCS) && !defined(lint) static const char sccsid[] = "@(#)res_send.c 8.1 (Berkeley) 6/4/93"; -static const char rcsid[] = "$Id: res_send.c,v 8.42 2001/03/07 06:48:03 marka Exp $"; +static const char rcsid[] = "$Id: res_send.c,v 8.48 2001/07/03 06:27:17 marka Exp $"; #endif /* LIBC_SCCS and not lint */ /* @@ -106,6 +106,7 @@ static const char rcsid[] = "$Id: res_send.c,v 8.42 2001/03/07 06:48:03 marka Ex /* Options. Leave them on. */ #define DEBUG #include "res_debug.h" +#include "res_private.h" #define EXT(res) ((res)->_u._ext) @@ -113,20 +114,25 @@ static const int highestFD = FD_SETSIZE - 1; /* Forward. */ +static int get_salen __P((const struct sockaddr *)); +static struct sockaddr * get_nsaddr __P((res_state, size_t)); static int send_vc(res_state, const u_char *, int, u_char *, int, int *, int); static int send_dg(res_state, const u_char *, int, u_char *, int, int *, int, int *, int *); static void Aerror(const res_state, FILE *, const char *, int, - struct sockaddr_in); + const struct sockaddr *, int); static void Perror(const res_state, FILE *, const char *, int); -static int sock_eq(struct sockaddr_in *, struct sockaddr_in *); +static int sock_eq(struct sockaddr *, struct sockaddr *); #ifdef NEED_PSELECT static int pselect(int, void *, void *, void *, struct timespec *, const sigset_t *); #endif +void res_pquery(const res_state, const u_char *, int, FILE *); + +static const int niflags = NI_NUMERICHOST | NI_NUMERICSERV; /* Public. */ @@ -140,19 +146,38 @@ static int pselect(int, void *, void *, void *, * paul vixie, 29may94 */ int -res_ourserver_p(const res_state statp, const struct sockaddr_in *inp) { - struct sockaddr_in ina; +res_ourserver_p(const res_state statp, const struct sockaddr *sa) { + const struct sockaddr_in *inp, *srv; + const struct sockaddr_in6 *in6p, *srv6; int ns; - ina = *inp; - for (ns = 0; ns < statp->nscount; ns++) { - const struct sockaddr_in *srv = &statp->nsaddr_list[ns]; - - if (srv->sin_family == ina.sin_family && - srv->sin_port == ina.sin_port && - (srv->sin_addr.s_addr == INADDR_ANY || - srv->sin_addr.s_addr == ina.sin_addr.s_addr)) - return (1); + switch (sa->sa_family) { + case AF_INET: + inp = (const struct sockaddr_in *)sa; + for (ns = 0; ns < statp->nscount; ns++) { + srv = (struct sockaddr_in *)get_nsaddr(statp, ns); + if (srv->sin_family == inp->sin_family && + srv->sin_port == inp->sin_port && + (srv->sin_addr.s_addr == INADDR_ANY || + srv->sin_addr.s_addr == inp->sin_addr.s_addr)) + return (1); + } + break; + case AF_INET6: + if (EXT(statp).ext == NULL) + break; + in6p = (const struct sockaddr_in6 *)sa; + for (ns = 0; ns < statp->nscount; ns++) { + srv6 = (struct sockaddr_in6 *)get_nsaddr(statp, ns); + if (srv6->sin6_family == in6p->sin6_family && + srv6->sin6_port == in6p->sin6_port && + (IN6_IS_ADDR_UNSPECIFIED(&srv6->sin6_addr) || + IN6_ARE_ADDR_EQUAL(&srv6->sin6_addr, &in6p->sin6_addr))) + return (1); + } + break; + default: + break; } return (0); } @@ -174,7 +199,7 @@ res_nameinquery(const char *name, int type, int class, const u_char *buf, const u_char *eom) { const u_char *cp = buf + HFIXEDSZ; - int qdcount = ntohs(((HEADER*)buf)->qdcount); + int qdcount = ntohs(((const HEADER*)buf)->qdcount); while (qdcount-- > 0) { char tname[MAXDNAME+1]; @@ -211,7 +236,7 @@ res_queriesmatch(const u_char *buf1, const u_char *eom1, const u_char *buf2, const u_char *eom2) { const u_char *cp = buf1 + HFIXEDSZ; - int qdcount = ntohs(((HEADER*)buf1)->qdcount); + int qdcount = ntohs(((const HEADER*)buf1)->qdcount); if (buf1 + HFIXEDSZ > eom1 || buf2 + HFIXEDSZ > eom2) return (-1); @@ -220,11 +245,11 @@ res_queriesmatch(const u_char *buf1, const u_char *eom1, * Only header section present in replies to * dynamic update packets. */ - if ((((HEADER *)buf1)->opcode == ns_o_update) && - (((HEADER *)buf2)->opcode == ns_o_update)) + if ((((const HEADER *)buf1)->opcode == ns_o_update) && + (((const HEADER *)buf2)->opcode == ns_o_update)) return (1); - if (qdcount != ntohs(((HEADER*)buf2)->qdcount)) + if (qdcount != ntohs(((const HEADER*)buf2)->qdcount)) return (0); while (qdcount-- > 0) { char tname[MAXDNAME+1]; @@ -249,6 +274,7 @@ res_nsend(res_state statp, const u_char *buf, int buflen, u_char *ans, int anssiz) { int gotsomewhere, terrno, try, v_circuit, resplen, ns, n; + char abuf[NI_MAXHOST]; if (statp->nscount == 0) { errno = ESRCH; @@ -270,16 +296,34 @@ res_nsend(res_state statp, */ if (EXT(statp).nscount != 0) { int needclose = 0; + struct sockaddr_storage peer; + ISC_SOCKLEN_T peerlen; if (EXT(statp).nscount != statp->nscount) needclose++; else - for (ns = 0; ns < statp->nscount; ns++) - if (!sock_eq(&statp->nsaddr_list[ns], - &EXT(statp).nsaddrs[ns])) { + for (ns = 0; ns < statp->nscount; ns++) { + if (statp->nsaddr_list[ns].sin_family && + !sock_eq((struct sockaddr *)&statp->nsaddr_list[ns], + (struct sockaddr *)&EXT(statp).ext->nsaddrs[ns])) { + needclose++; + break; + } + + if (EXT(statp).nssocks[ns] == -1) + continue; + peerlen = sizeof(peer); + if (getsockname(EXT(statp).nssocks[ns], + (struct sockaddr *)&peer, &peerlen) < 0) { + needclose++; + break; + } + if (!sock_eq((struct sockaddr *)&peer, + get_nsaddr(statp, ns))) { needclose++; break; } + } if (needclose) { res_nclose(statp); EXT(statp).nscount = 0; @@ -291,9 +335,12 @@ res_nsend(res_state statp, */ if (EXT(statp).nscount == 0) { for (ns = 0; ns < statp->nscount; ns++) { - EXT(statp).nsaddrs[ns] = statp->nsaddr_list[ns]; EXT(statp).nstimes[ns] = RES_MAXTIME; EXT(statp).nssocks[ns] = -1; + if (!statp->nsaddr_list[ns].sin_family) + continue; + EXT(statp).ext->nsaddrs[ns].sin = + statp->nsaddr_list[ns]; } EXT(statp).nscount = statp->nscount; } @@ -304,19 +351,27 @@ res_nsend(res_state statp, */ if ((statp->options & RES_ROTATE) != 0 && (statp->options & RES_BLAST) == 0) { + union res_sockaddr_union inu; struct sockaddr_in ina; int lastns = statp->nscount - 1; int fd; u_int16_t nstime; + if (EXT(statp).ext != NULL) + inu = EXT(statp).ext->nsaddrs[0]; ina = statp->nsaddr_list[0]; fd = EXT(statp).nssocks[0]; - nstime = EXT(statp).nstimes[ns]; + nstime = EXT(statp).nstimes[0]; for (ns = 0; ns < lastns; ns++) { + if (EXT(statp).ext != NULL) + EXT(statp).ext->nsaddrs[ns] = + EXT(statp).ext->nsaddrs[ns + 1]; statp->nsaddr_list[ns] = statp->nsaddr_list[ns + 1]; EXT(statp).nssocks[ns] = EXT(statp).nssocks[ns + 1]; EXT(statp).nstimes[ns] = EXT(statp).nstimes[ns + 1]; } + if (EXT(statp).ext != NULL) + EXT(statp).ext->nsaddrs[lastns] = inu; statp->nsaddr_list[lastns] = ina; EXT(statp).nssocks[lastns] = fd; EXT(statp).nstimes[lastns] = nstime; @@ -327,7 +382,10 @@ res_nsend(res_state statp, */ for (try = 0; try < statp->retry; try++) { for (ns = 0; ns < statp->nscount; ns++) { - struct sockaddr_in *nsap = &statp->nsaddr_list[ns]; + struct sockaddr *nsap; + int nsaplen; + nsap = get_nsaddr(statp, ns); + nsaplen = get_salen(nsap); same_ns: if (statp->qhook) { int done = 0, loops = 0; @@ -359,9 +417,12 @@ res_nsend(res_state statp, } while (!done); } - Dprint(statp->options & RES_DEBUG, + Dprint(((statp->options & RES_DEBUG) && + getnameinfo(nsap, nsaplen, abuf, sizeof(abuf), + NULL, 0, niflags) == 0), (stdout, ";; Querying server (# %d) address = %s\n", - ns + 1, inet_ntoa(nsap->sin_addr))); + ns + 1, abuf)); + if (v_circuit) { /* Use VC; at most one attempt per server. */ @@ -393,7 +454,7 @@ res_nsend(res_state statp, DprintQ((statp->options & RES_DEBUG) || (statp->pfcode & RES_PRF_REPLY), - (stdout, ""), + (stdout, "%s", ""), ans, (resplen > anssiz) ? anssiz : resplen); /* @@ -455,17 +516,67 @@ res_nsend(res_state statp, /* Private */ static int +get_salen(sa) + const struct sockaddr *sa; +{ + +#ifdef HAVE_SA_LEN + /* there are people do not set sa_len. be forgibing to them */ + if (sa->sa_len) + return sa->sa_len; +#endif + + if (sa->sa_family == AF_INET) + return sizeof(struct sockaddr_in); + else if (sa->sa_family == AF_INET) + return sizeof(struct sockaddr_in6); + else + return 0; /* unknown, die on connect */ +} + +/* + * pick appropriate nsaddr_list for use. see res_init() for initialization. + */ +static struct sockaddr * +get_nsaddr(statp, n) + res_state statp; + size_t n; +{ + + if (!statp->nsaddr_list[n].sin_family && EXT(statp).ext) { + /* + * - EXT(statp).ext->nsaddrs[n] holds an address that is larger + * than struct sockaddr, and + * - user code did not update statp->nsaddr_list[n]. + */ + return (struct sockaddr *)(void *)&EXT(statp).ext->nsaddrs[n]; + } else { + /* + * - user code updated statp->nsaddr_list[n], or + * - statp->nsaddr_list[n] has the same content as + * EXT(statp).ext->nsaddrs[n]. + */ + return (struct sockaddr *)(void *)&statp->nsaddr_list[n]; + } +} + +static int send_vc(res_state statp, const u_char *buf, int buflen, u_char *ans, int anssiz, int *terrno, int ns) { - const HEADER *hp = (HEADER *) buf; + const HEADER *hp = (const HEADER *) buf; HEADER *anhp = (HEADER *) ans; - struct sockaddr_in *nsap = &statp->nsaddr_list[ns]; + struct sockaddr *nsap; + int nsaplen; int truncating, connreset, resplen, n; struct iovec iov[2]; u_short len; u_char *cp; + void *tmp; + + nsap = get_nsaddr(statp, ns); + nsaplen = get_salen(nsap); connreset = 0; same_ns: @@ -473,12 +584,12 @@ send_vc(res_state statp, /* Are we still talking to whom we want to talk to? */ if (statp->_vcsock >= 0 && (statp->_flags & RES_F_VC) != 0) { - struct sockaddr_in peer; - int size = sizeof peer; + struct sockaddr_storage peer; + ISC_SOCKLEN_T size = sizeof peer; if (getpeername(statp->_vcsock, (struct sockaddr *)&peer, &size) < 0 || - !sock_eq(&peer, nsap)) { + !sock_eq((struct sockaddr *)&peer, nsap)) { res_nclose(statp); statp->_flags &= ~RES_F_VC; } @@ -488,7 +599,7 @@ send_vc(res_state statp, if (statp->_vcsock >= 0) res_nclose(statp); - statp->_vcsock = socket(PF_INET, SOCK_STREAM, 0); + statp->_vcsock = socket(nsap->sa_family, SOCK_STREAM, 0); if (statp->_vcsock > highestFD) { res_nclose(statp); errno = ENOTSOCK; @@ -499,10 +610,10 @@ send_vc(res_state statp, return (-1); } errno = 0; - if (connect(statp->_vcsock, (struct sockaddr *)nsap, - sizeof *nsap) < 0) { + if (connect(statp->_vcsock, nsap, nsaplen) < 0) { *terrno = errno; - Aerror(statp, stderr, "connect/vc", errno, *nsap); + Aerror(statp, stderr, "connect/vc", errno, nsap, + nsaplen); res_nclose(statp); return (0); } @@ -514,7 +625,8 @@ send_vc(res_state statp, */ putshort((u_short)buflen, (u_char*)&len); iov[0] = evConsIovec(&len, INT16SZ); - iov[1] = evConsIovec((void*)buf, buflen); + DE_CONST(buf, tmp); + iov[1] = evConsIovec(tmp, buflen); if (writev(statp->_vcsock, iov, 2) != (INT16SZ + buflen)) { *terrno = errno; Perror(statp, stderr, "write failed", errno); @@ -627,16 +739,20 @@ send_dg(res_state statp, const u_char *buf, int buflen, u_char *ans, int anssiz, int *terrno, int ns, int *v_circuit, int *gotsomewhere) { - const HEADER *hp = (HEADER *) buf; + const HEADER *hp = (const HEADER *) buf; HEADER *anhp = (HEADER *) ans; - const struct sockaddr_in *nsap = &statp->nsaddr_list[ns]; + const struct sockaddr *nsap; + int nsaplen; struct timespec now, timeout, finish; fd_set dsmask; - struct sockaddr_in from; - int fromlen, resplen, seconds, n, s; + struct sockaddr_storage from; + ISC_SOCKLEN_T fromlen; + int resplen, seconds, n, s; + nsap = get_nsaddr(statp, ns); + nsaplen = get_salen(nsap); if (EXT(statp).nssocks[ns] == -1) { - EXT(statp).nssocks[ns] = socket(PF_INET, SOCK_DGRAM, 0); + EXT(statp).nssocks[ns] = socket(nsap->sa_family, SOCK_DGRAM, 0); if (EXT(statp).nssocks[ns] > highestFD) { res_nclose(statp); errno = ENOTSOCK; @@ -658,9 +774,9 @@ send_dg(res_state statp, * error message is received. We can thus detect * the absence of a nameserver without timing out. */ - if (connect(EXT(statp).nssocks[ns], (struct sockaddr *)nsap, - sizeof *nsap) < 0) { - Aerror(statp, stderr, "connect(dg)", errno, *nsap); + if (connect(EXT(statp).nssocks[ns], nsap, nsaplen) < 0) { + Aerror(statp, stderr, "connect(dg)", errno, nsap, + nsaplen); res_nclose(statp); return (0); } @@ -670,16 +786,15 @@ send_dg(res_state statp, } s = EXT(statp).nssocks[ns]; #ifndef CANNOT_CONNECT_DGRAM - if (send(s, (char*)buf, buflen, 0) != buflen) { + if (send(s, (const char*)buf, buflen, 0) != buflen) { Perror(statp, stderr, "send", errno); res_nclose(statp); return (0); } #else /* !CANNOT_CONNECT_DGRAM */ - if (sendto(s, (char*)buf, buflen, 0, - (struct sockaddr *)nsap, sizeof *nsap) != buflen) + if (sendto(s, (const char*)buf, buflen, 0, nsap, nsaplen) != buflen) { - Aerror(statp, stderr, "sendto", errno, *nsap); + Aerror(statp, stderr, "sendto", errno, nsap, nsaplen); res_nclose(statp); return (0); } @@ -720,7 +835,7 @@ send_dg(res_state statp, return (0); } errno = 0; - fromlen = sizeof(struct sockaddr_in); + fromlen = sizeof(from); resplen = recvfrom(s, (char*)ans, anssiz,0, (struct sockaddr *)&from, &fromlen); if (resplen <= 0) { @@ -753,7 +868,7 @@ send_dg(res_state statp, goto wait; } if (!(statp->options & RES_INSECURE1) && - !res_ourserver_p(statp, &from)) { + !res_ourserver_p(statp, (struct sockaddr *)&from)) { /* * response from wrong server? ignore it. * XXX - potential security hazard could @@ -765,6 +880,22 @@ send_dg(res_state statp, ans, (resplen > anssiz) ? anssiz : resplen); goto wait; } +#ifdef RES_USE_EDNS0 + if (anhp->rcode == FORMERR && (statp->options & RES_USE_EDNS0) != 0) { + /* + * Do not retry if the server do not understand EDNS0. + * The case has to be captured here, as FORMERR packet do not + * carry query section, hence res_queriesmatch() returns 0. + */ + DprintQ(statp->options & RES_DEBUG, + (stdout, "server rejected query with EDNS0:\n"), + ans, (resplen > anssiz) ? anssiz : resplen); + /* record the error */ + statp->_flags |= RES_F_EDNS0ERR; + res_nclose(statp); + return (0); + } +#endif if (!(statp->options & RES_INSECURE2) && !res_queriesmatch(buf, buf + buflen, ans, ans + anssiz)) { @@ -810,19 +941,24 @@ send_dg(res_state statp, static void Aerror(const res_state statp, FILE *file, const char *string, int error, - struct sockaddr_in address) + const struct sockaddr *address, int alen) { int save = errno; + char hbuf[NI_MAXHOST]; + char sbuf[NI_MAXSERV]; - if ((statp->options & RES_DEBUG) != 0) { - char tmp[sizeof "255.255.255.255"]; + alen = alen; - fprintf(file, "res_send: %s ([%s].%u): %s\n", - string, - inet_ntop(address.sin_family, &address.sin_addr, - tmp, sizeof tmp), - ntohs(address.sin_port), - strerror(error)); + if ((statp->options & RES_DEBUG) != 0) { + if (getnameinfo(address, alen, hbuf, sizeof(hbuf), + sbuf, sizeof(sbuf), niflags)) { + strncpy(hbuf, "?", sizeof(hbuf) - 1); + hbuf[sizeof(hbuf) - 1] = '\0'; + strncpy(sbuf, "?", sizeof(sbuf) - 1); + sbuf[sizeof(sbuf) - 1] = '\0'; + } + fprintf(file, "res_send: %s ([%s].%s): %s\n", + string, hbuf, sbuf, strerror(error)); } errno = save; } @@ -838,10 +974,29 @@ Perror(const res_state statp, FILE *file, const char *string, int error) { } static int -sock_eq(struct sockaddr_in *a1, struct sockaddr_in *a2) { - return ((a1->sin_family == a2->sin_family) && - (a1->sin_port == a2->sin_port) && - (a1->sin_addr.s_addr == a2->sin_addr.s_addr)); +sock_eq(struct sockaddr *a, struct sockaddr *b) { + struct sockaddr_in *a4, *b4; + struct sockaddr_in6 *a6, *b6; + + if (a->sa_family != b->sa_family) + return 0; + switch (a->sa_family) { + case AF_INET: + a4 = (struct sockaddr_in *)a; + b4 = (struct sockaddr_in *)b; + return a4->sin_port == b4->sin_port && + a4->sin_addr.s_addr == b4->sin_addr.s_addr; + case AF_INET6: + a6 = (struct sockaddr_in6 *)a; + b6 = (struct sockaddr_in6 *)b; + return a6->sin6_port == b6->sin6_port && +#ifdef HAVE_SIN6_SCOPE_ID + a6->sin6_scope_id == b6->sin6_scope_id && +#endif + IN6_ARE_ADDR_EQUAL(&a6->sin6_addr, &b6->sin6_addr); + default: + return 0; + } } #ifdef NEED_PSELECT diff --git a/contrib/bind/lib/resolv/res_update.c b/contrib/bind/lib/resolv/res_update.c index 1434d5c..54d3b15 100644 --- a/contrib/bind/lib/resolv/res_update.c +++ b/contrib/bind/lib/resolv/res_update.c @@ -1,5 +1,5 @@ #if !defined(lint) && !defined(SABER) -static const char rcsid[] = "$Id: res_update.c,v 1.26 2001/03/05 04:03:00 marka Exp $"; +static const char rcsid[] = "$Id: res_update.c,v 1.31 2001/11/01 05:21:23 marka Exp $"; #endif /* not lint */ /* @@ -37,7 +37,6 @@ static const char rcsid[] = "$Id: res_update.c,v 1.26 2001/03/05 04:03:00 marka #include <errno.h> #include <limits.h> #include <netdb.h> -#include <resolv.h> #include <res_update.h> #include <stdarg.h> #include <stdio.h> @@ -45,8 +44,10 @@ static const char rcsid[] = "$Id: res_update.c,v 1.26 2001/03/05 04:03:00 marka #include <string.h> #include <isc/list.h> +#include <resolv.h> #include "port_after.h" +#include "res_private.h" /* * Separate a linked list of records into groups so that all records @@ -65,7 +66,7 @@ static const char rcsid[] = "$Id: res_update.c,v 1.26 2001/03/05 04:03:00 marka struct zonegrp { char z_origin[MAXDNAME]; ns_class z_class; - struct in_addr z_nsaddrs[MAXNS]; + union res_sockaddr_union z_nsaddrs[MAXNS]; int z_nscount; int z_flags; LIST(ns_updrec) z_rrlist; @@ -76,15 +77,15 @@ struct zonegrp { /* Forward. */ -static int nscopy(struct sockaddr_in *, const struct sockaddr_in *, int); -static int nsprom(struct sockaddr_in *, const struct in_addr *, int); -static void dprintf(const char *, ...); +static int nscopy(union res_sockaddr_union *, + const union res_sockaddr_union *, int); +static void res_dprintf(const char *, ...); /* Macros. */ #define DPRINTF(x) do {\ int save_errno = errno; \ - if ((statp->options & RES_DEBUG) != 0) dprintf x; \ + if ((statp->options & RES_DEBUG) != 0) res_dprintf x; \ errno = save_errno; \ } while (0) @@ -97,12 +98,20 @@ res_nupdate(res_state statp, ns_updrec *rrecp_in, ns_tsig_key *key) { struct zonegrp *zptr, tgrp; LIST(struct zonegrp) zgrps; int nzones = 0, nscount = 0, n; - struct sockaddr_in nsaddrs[MAXNS]; + union res_sockaddr_union nsaddrs[MAXNS]; /* Thread all of the updates onto a list of groups. */ INIT_LIST(zgrps); for (rrecp = rrecp_in; rrecp; rrecp = LINKED(rrecp, r_link) ? NEXT(rrecp, r_link) : NULL) { + struct in_addr nsaddrs[MAXNS]; + int i; + /* XXX need to rewrite res_findzonecut */ + for (i = 0; i < MAXNS; i++) { + nsaddrs[i].s_addr = 0; + if (tgrp.z_nsaddrs[i].sin.sin_family == AF_INET) + nsaddrs[i] = tgrp.z_nsaddrs[i].sin.sin_addr; + } /* Find the origin for it if there is one. */ tgrp.z_class = rrecp->r_class; tgrp.z_nscount = @@ -110,7 +119,7 @@ res_nupdate(res_state statp, ns_updrec *rrecp_in, ns_tsig_key *key) { RES_EXHAUSTIVE, tgrp.z_origin, sizeof tgrp.z_origin, - tgrp.z_nsaddrs, MAXNS); + nsaddrs, MAXNS); if (tgrp.z_nscount <= 0) { DPRINTF(("res_findzonecut failed (%d)", tgrp.z_nscount)); @@ -157,8 +166,8 @@ res_nupdate(res_state statp, ns_updrec *rrecp_in, ns_tsig_key *key) { goto done; /* Temporarily replace the resolver's nameserver set. */ - nscount = nscopy(nsaddrs, statp->nsaddr_list, statp->nscount); - statp->nscount = nsprom(statp->nsaddr_list, + nscount = nscopy(nsaddrs, statp->_u._ext.ext->nsaddrs, statp->nscount); + statp->nscount = nscopy(statp->_u._ext.ext->nsaddrs, zptr->z_nsaddrs, zptr->z_nscount); /* Send the update and remember the result. */ @@ -176,7 +185,7 @@ res_nupdate(res_state statp, ns_updrec *rrecp_in, ns_tsig_key *key) { nzones++; /* Restore resolver's nameserver set. */ - statp->nscount = nscopy(statp->nsaddr_list, nsaddrs, nscount); + statp->nscount = nscopy(statp->_u._ext.ext->nsaddrs, nsaddrs, nscount); nscount = 0; } done: @@ -188,7 +197,7 @@ res_nupdate(res_state statp, ns_updrec *rrecp_in, ns_tsig_key *key) { free(zptr); } if (nscount != 0) - statp->nscount = nscopy(statp->nsaddr_list, nsaddrs, nscount); + statp->nscount = nscopy(statp->_u._ext.ext->nsaddrs, nsaddrs, nscount); return (nzones); } @@ -196,7 +205,9 @@ res_nupdate(res_state statp, ns_updrec *rrecp_in, ns_tsig_key *key) { /* Private. */ static int -nscopy(struct sockaddr_in *dst, const struct sockaddr_in *src, int n) { +nscopy(union res_sockaddr_union *dst, const union res_sockaddr_union *src, + int n) +{ int i; for (i = 0; i < n; i++) @@ -204,21 +215,8 @@ nscopy(struct sockaddr_in *dst, const struct sockaddr_in *src, int n) { return (n); } -static int -nsprom(struct sockaddr_in *dst, const struct in_addr *src, int n) { - int i; - - for (i = 0; i < n; i++) { - memset(&dst[i], 0, sizeof dst[i]); - dst[i].sin_family = AF_INET; - dst[i].sin_port = htons(NS_DEFAULTPORT); - dst[i].sin_addr = src[i]; - } - return (n); -} - static void -dprintf(const char *fmt, ...) { +res_dprintf(const char *fmt, ...) { va_list ap; va_start(ap, fmt); |