1
0
mirror of https://git.FreeBSD.org/src.git synced 2024-12-02 08:42:48 +00:00

Update the resolver parts to bind-8.1.2 level. I have not touched the

getXXXXbyYYYY() interfaces yet.

Obtained from: diff relative to bind-8.1.2 sources
This commit is contained in:
Peter Wemm 1998-06-11 09:03:02 +00:00
parent a28ce30ec5
commit 14b93edab3
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=36891
25 changed files with 3224 additions and 1738 deletions

View File

@ -1,5 +1,5 @@
# from @(#)Makefile.inc 8.2 (Berkeley) 9/5/93 # from @(#)Makefile.inc 8.2 (Berkeley) 9/5/93
# $Id: Makefile.inc,v 1.25 1997/10/21 08:41:08 bde Exp $ # $Id: Makefile.inc,v 1.26 1998/02/20 08:15:55 jb Exp $
# machine-independent net sources # machine-independent net sources
.PATH: ${.CURDIR}/../libc/${MACHINE_ARCH}/net ${.CURDIR}/../libc/net .PATH: ${.CURDIR}/../libc/${MACHINE_ARCH}/net ${.CURDIR}/../libc/net
@ -11,10 +11,11 @@ SRCS+= addr2ascii.c ascii2addr.c base64.c ether_addr.c \
getservbyport.c getservent.c herror.c inet_addr.c inet_lnaof.c \ getservbyport.c getservent.c herror.c inet_addr.c inet_lnaof.c \
inet_makeaddr.c inet_net_ntop.c inet_net_pton.c inet_neta.c \ inet_makeaddr.c inet_net_ntop.c inet_net_pton.c inet_neta.c \
inet_netof.c inet_network.c inet_ntoa.c inet_ntop.c \ inet_netof.c inet_network.c inet_ntoa.c inet_ntop.c \
inet_pton.c linkaddr.c map_v4v6.c ns_addr.c ns_ntoa.c nsap_addr.c \ inet_pton.c linkaddr.c map_v4v6.c ns_addr.c ns_name.c ns_netint.c \
ns_ntoa.c ns_parse.c ns_print.c ns_ttl.c nsap_addr.c \
rcmd.c recv.c res_comp.c res_data.c res_debug.c \ rcmd.c recv.c res_comp.c res_data.c res_debug.c \
res_init.c res_mkquery.c res_query.c res_send.c res_stubs.c \ res_init.c res_mkquery.c res_mkupdate.c res_query.c res_send.c \
send.c res_stubs.c res_update.c send.c
# not supported: iso_addr.c # not supported: iso_addr.c
# machine-dependent net sources # machine-dependent net sources

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1996 by Internet Software Consortium. * Copyright (c) 1996, 1998 by Internet Software Consortium.
* *
* Permission to use, copy, modify, and distribute this software for any * Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above * purpose with or without fee is hereby granted, provided that the above
@ -40,9 +40,14 @@
* IF IBM IS APPRISED OF THE POSSIBILITY OF SUCH DAMAGES. * IF IBM IS APPRISED OF THE POSSIBILITY OF SUCH DAMAGES.
*/ */
#if !defined(LINT) && !defined(CODECENTER)
static char rcsid[] = "$Id: base64.c,v 8.5 1998/03/27 00:17:46 halley Exp $";
#endif /* not lint */
#include <sys/types.h> #include <sys/types.h>
#include <sys/param.h> #include <sys/param.h>
#include <sys/socket.h> #include <sys/socket.h>
#include <netinet/in.h> #include <netinet/in.h>
#include <arpa/inet.h> #include <arpa/inet.h>
#include <arpa/nameser.h> #include <arpa/nameser.h>
@ -50,13 +55,8 @@
#include <ctype.h> #include <ctype.h>
#include <resolv.h> #include <resolv.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h>
#if defined(BSD) && (BSD >= 199103) && defined(AF_INET6) #include <string.h>
# include <stdlib.h>
# include <string.h>
#else
# include "../conf/portability.h"
#endif
#define Assert(Cond) if (!(Cond)) abort() #define Assert(Cond) if (!(Cond)) abort()
@ -128,16 +128,11 @@ static const char Pad64 = '=';
*/ */
int int
b64_ntop(src, srclength, target, targsize) b64_ntop(u_char const *src, size_t srclength, char *target, size_t targsize) {
u_char const *src;
size_t srclength;
char *target;
size_t targsize;
{
size_t datalength = 0; size_t datalength = 0;
u_char input[3]; u_char input[3];
u_char output[4]; u_char output[4];
int i; size_t i;
while (2 < srclength) { while (2 < srclength) {
input[0] = *src++; input[0] = *src++;
@ -224,7 +219,7 @@ b64_pton(src, target, targsize)
switch (state) { switch (state) {
case 0: case 0:
if (target) { if (target) {
if (tarindex >= targsize) if ((size_t)tarindex >= targsize)
return (-1); return (-1);
target[tarindex] = (pos - Base64) << 2; target[tarindex] = (pos - Base64) << 2;
} }
@ -232,7 +227,7 @@ b64_pton(src, target, targsize)
break; break;
case 1: case 1:
if (target) { if (target) {
if (tarindex + 1 >= targsize) if ((size_t)tarindex + 1 >= targsize)
return (-1); return (-1);
target[tarindex] |= (pos - Base64) >> 4; target[tarindex] |= (pos - Base64) >> 4;
target[tarindex+1] = ((pos - Base64) & 0x0f) target[tarindex+1] = ((pos - Base64) & 0x0f)
@ -243,7 +238,7 @@ b64_pton(src, target, targsize)
break; break;
case 2: case 2:
if (target) { if (target) {
if (tarindex + 1 >= targsize) if ((size_t)tarindex + 1 >= targsize)
return (-1); return (-1);
target[tarindex] |= (pos - Base64) >> 2; target[tarindex] |= (pos - Base64) >> 2;
target[tarindex+1] = ((pos - Base64) & 0x03) target[tarindex+1] = ((pos - Base64) & 0x03)
@ -254,7 +249,7 @@ b64_pton(src, target, targsize)
break; break;
case 3: case 3:
if (target) { if (target) {
if (tarindex >= targsize) if ((size_t)tarindex >= targsize)
return (-1); return (-1);
target[tarindex] |= (pos - Base64); target[tarindex] |= (pos - Base64);
} }
@ -280,7 +275,7 @@ b64_pton(src, target, targsize)
case 2: /* Valid, means one byte of info */ case 2: /* Valid, means one byte of info */
/* Skip any number of spaces. */ /* Skip any number of spaces. */
for (NULL; ch != '\0'; ch = *src++) for ((void)NULL; ch != '\0'; ch = *src++)
if (!isspace(ch)) if (!isspace(ch))
break; break;
/* Make sure there is another trailing = sign. */ /* Make sure there is another trailing = sign. */
@ -295,7 +290,7 @@ b64_pton(src, target, targsize)
* We know this char is an =. Is there anything but * We know this char is an =. Is there anything but
* whitespace after it? * whitespace after it?
*/ */
for (NULL; ch != '\0'; ch = *src++) for ((void)NULL; ch != '\0'; ch = *src++)
if (!isspace(ch)) if (!isspace(ch))
return (-1); return (-1);

View File

@ -1,4 +1,4 @@
/*- /*
* Copyright (c) 1987, 1993 * Copyright (c) 1987, 1993
* The Regents of the University of California. All rights reserved. * The Regents of the University of California. All rights reserved.
* *
@ -29,38 +29,35 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * 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 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE. * SUCH DAMAGE.
* - */
* Portions Copyright (c) 1993 by Digital Equipment Corporation.
/*
* Portions Copyright (c) 1996 by Internet Software Consortium.
* *
* Permission to use, copy, modify, and distribute this software for any * Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above * purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies, and that * copyright notice and this permission notice appear in all copies.
* the name of Digital Equipment Corporation not be used in advertising or
* publicity pertaining to distribution of the document or software without
* specific, written prior permission.
* *
* THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
* WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
* CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS * 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 * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
* SOFTWARE. * SOFTWARE.
* -
* --Copyright--
*/ */
#if defined(LIBC_SCCS) && !defined(lint) #if defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "@(#)herror.c 8.1 (Berkeley) 6/4/93"; static char sccsid[] = "@(#)herror.c 8.1 (Berkeley) 6/4/93";
static char rcsid[] = "$Id$"; static char rcsid[] = "$Id: herror.c,v 1.6 1997/02/22 15:00:14 peter Exp $";
#endif /* LIBC_SCCS and not lint */ #endif /* LIBC_SCCS and not lint */
#include <sys/types.h> #include <sys/types.h>
#include <sys/uio.h> #include <sys/uio.h>
#include <netdb.h> #include <netdb.h>
#include <unistd.h>
#include <string.h> #include <string.h>
#include <unistd.h>
const char *h_errlist[] = { const char *h_errlist[] = {
"Resolver Error 0 (no error)", "Resolver Error 0 (no error)",
@ -71,7 +68,7 @@ const char *h_errlist[] = {
}; };
int h_nerr = { sizeof h_errlist / sizeof h_errlist[0] }; int h_nerr = { sizeof h_errlist / sizeof h_errlist[0] };
extern int h_errno; int h_errno;
/* /*
* herror -- * herror --

View File

@ -16,8 +16,8 @@
*/ */
#if defined(LIBC_SCCS) && !defined(lint) #if defined(LIBC_SCCS) && !defined(lint)
static const char orig_rcsid[] = "From Id: inet_net_pton.c,v 8.3 1996/11/11 06:36:52 vixie Exp"; static const char orig_rcsid[] = "From Id: inet_net_pton.c,v 1.8 1996/11/21 10:28:12 vixie Exp $";
static const char rcsid[] = "$Id$"; static const char rcsid[] = "$Id: inet_net_pton.c,v 1.3 1997/02/22 15:00:18 peter Exp $";
#endif #endif
#include <sys/types.h> #include <sys/types.h>
@ -159,8 +159,7 @@ inet_net_pton_ipv4(src, dst, size)
assert(n >= 0 && n <= 9); assert(n >= 0 && n <= 9);
bits *= 10; bits *= 10;
bits += n; bits += n;
} while ((ch = *src++) != '\0' && } while ((ch = *src++) != '\0' && isascii(ch) && isdigit(ch));
isascii(ch) && isdigit(ch));
if (ch != '\0') if (ch != '\0')
goto enoent; goto enoent;
if (bits > 32) if (bits > 32)

View File

@ -49,10 +49,9 @@ u_long
inet_network(cp) inet_network(cp)
register const char *cp; register const char *cp;
{ {
register u_long val, base, n; register u_long val, base, n, i;
register char c; register char c;
u_long parts[4], *pp = parts; u_long parts[4], *pp = parts;
register int i;
again: again:
val = 0; base = 10; val = 0; base = 10;
@ -60,7 +59,7 @@ inet_network(cp)
base = 8, cp++; base = 8, cp++;
if (*cp == 'x' || *cp == 'X') if (*cp == 'x' || *cp == 'X')
base = 16, cp++; base = 16, cp++;
while ( (c = *cp) ) { while ((c = *cp) != 0) {
if (isdigit(c)) { if (isdigit(c)) {
val = (val * base) + (c - '0'); val = (val * base) + (c - '0');
cp++; cp++;

View File

@ -35,25 +35,23 @@
static char sccsid[] = "@(#)inet_ntoa.c 8.1 (Berkeley) 6/4/93"; static char sccsid[] = "@(#)inet_ntoa.c 8.1 (Berkeley) 6/4/93";
#endif /* LIBC_SCCS and not lint */ #endif /* LIBC_SCCS and not lint */
/*
* Convert network-format internet address
* to base 256 d.d.d.d representation.
*/
#include <sys/types.h> #include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h> #include <netinet/in.h>
#include <arpa/inet.h> #include <arpa/inet.h>
#include <stdio.h> #include <stdio.h>
/*
* Convert network-format internet address
* to base 256 d.d.d.d representation.
*/
char * char *
inet_ntoa(in) inet_ntoa(in)
struct in_addr in; struct in_addr in;
{ {
static char b[18]; static char ret[18];
register char *p;
p = (char *)&in; strcpy(ret, "[inet_ntoa error]");
#define UC(b) (((int)b)&0xff) (void) inet_ntop(AF_INET, &in, ret, sizeof ret);
(void)snprintf(b, sizeof(b), return (ret);
"%d.%d.%d.%d", UC(p[0]), UC(p[1]), UC(p[2]), UC(p[3]));
return (b);
} }

View File

@ -15,7 +15,7 @@
*/ */
#if defined(LIBC_SCCS) && !defined(lint) #if defined(LIBC_SCCS) && !defined(lint)
static char rcsid[] = "$Id$"; static char rcsid[] = "$Id: inet_ntop.c,v 1.3 1997/02/22 15:00:21 peter Exp $";
#endif /* LIBC_SCCS and not lint */ #endif /* LIBC_SCCS and not lint */
#include <sys/param.h> #include <sys/param.h>
@ -24,9 +24,9 @@ static char rcsid[] = "$Id$";
#include <netinet/in.h> #include <netinet/in.h>
#include <arpa/inet.h> #include <arpa/inet.h>
#include <arpa/nameser.h> #include <arpa/nameser.h>
#include <string.h>
#include <errno.h> #include <errno.h>
#include <stdio.h> #include <stdio.h>
#include <string.h>
#define SPRINTF(x) ((size_t)sprintf x) #define SPRINTF(x) ((size_t)sprintf x)
@ -114,7 +114,7 @@ inet_ntop6(src, dst, size)
*/ */
char tmp[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"], *tp; char tmp[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"], *tp;
struct { int base, len; } best, cur; struct { int base, len; } best, cur;
u_int words[IN6ADDRSZ / INT16SZ]; u_int words[NS_IN6ADDRSZ / NS_INT16SZ];
int i; int i;
/* /*
@ -123,11 +123,11 @@ inet_ntop6(src, dst, size)
* Find the longest run of 0x00's in src[] for :: shorthanding. * Find the longest run of 0x00's in src[] for :: shorthanding.
*/ */
memset(words, '\0', sizeof words); memset(words, '\0', sizeof words);
for (i = 0; i < IN6ADDRSZ; i++) for (i = 0; i < NS_IN6ADDRSZ; i++)
words[i / 2] |= (src[i] << ((1 - (i % 2)) << 3)); words[i / 2] |= (src[i] << ((1 - (i % 2)) << 3));
best.base = -1; best.base = -1;
cur.base = -1; cur.base = -1;
for (i = 0; i < (IN6ADDRSZ / INT16SZ); i++) { for (i = 0; i < (NS_IN6ADDRSZ / NS_INT16SZ); i++) {
if (words[i] == 0) { if (words[i] == 0) {
if (cur.base == -1) if (cur.base == -1)
cur.base = i, cur.len = 1; cur.base = i, cur.len = 1;
@ -152,7 +152,7 @@ inet_ntop6(src, dst, size)
* Format the result. * Format the result.
*/ */
tp = tmp; tp = tmp;
for (i = 0; i < (IN6ADDRSZ / INT16SZ); i++) { for (i = 0; i < (NS_IN6ADDRSZ / NS_INT16SZ); i++) {
/* Are we inside the best run of 0x00's? */ /* Are we inside the best run of 0x00's? */
if (best.base != -1 && i >= best.base && if (best.base != -1 && i >= best.base &&
i < (best.base + best.len)) { i < (best.base + best.len)) {
@ -174,7 +174,8 @@ inet_ntop6(src, dst, size)
tp += SPRINTF((tp, "%x", words[i])); tp += SPRINTF((tp, "%x", words[i]));
} }
/* Was it a trailing run of 0x00's? */ /* Was it a trailing run of 0x00's? */
if (best.base != -1 && (best.base + best.len) == (IN6ADDRSZ / INT16SZ)) if (best.base != -1 && (best.base + best.len) ==
(NS_IN6ADDRSZ / NS_INT16SZ))
*tp++ = ':'; *tp++ = ':';
*tp++ = '\0'; *tp++ = '\0';

View File

@ -15,7 +15,7 @@
*/ */
#if defined(LIBC_SCCS) && !defined(lint) #if defined(LIBC_SCCS) && !defined(lint)
static char rcsid[] = "$Id$"; static char rcsid[] = "$Id: inet_pton.c,v 1.3 1997/02/22 15:00:22 peter Exp $";
#endif /* LIBC_SCCS and not lint */ #endif /* LIBC_SCCS and not lint */
#include <sys/param.h> #include <sys/param.h>
@ -81,7 +81,7 @@ inet_pton4(src, dst)
{ {
static const char digits[] = "0123456789"; static const char digits[] = "0123456789";
int saw_digit, octets, ch; int saw_digit, octets, ch;
u_char tmp[INADDRSZ], *tp; u_char tmp[NS_INADDRSZ], *tp;
saw_digit = 0; saw_digit = 0;
octets = 0; octets = 0;
@ -111,7 +111,7 @@ inet_pton4(src, dst)
if (octets < 4) if (octets < 4)
return (0); return (0);
memcpy(dst, tmp, INADDRSZ); memcpy(dst, tmp, NS_INADDRSZ);
return (1); return (1);
} }
@ -135,13 +135,13 @@ inet_pton6(src, dst)
{ {
static const char xdigits_l[] = "0123456789abcdef", static const char xdigits_l[] = "0123456789abcdef",
xdigits_u[] = "0123456789ABCDEF"; xdigits_u[] = "0123456789ABCDEF";
u_char tmp[IN6ADDRSZ], *tp, *endp, *colonp; u_char tmp[NS_IN6ADDRSZ], *tp, *endp, *colonp;
const char *xdigits, *curtok; const char *xdigits, *curtok;
int ch, saw_xdigit; int ch, saw_xdigit;
u_int val; u_int val;
memset((tp = tmp), '\0', IN6ADDRSZ); memset((tp = tmp), '\0', NS_IN6ADDRSZ);
endp = tp + IN6ADDRSZ; endp = tp + NS_IN6ADDRSZ;
colonp = NULL; colonp = NULL;
/* Leading :: requires some special handling. */ /* Leading :: requires some special handling. */
if (*src == ':') if (*src == ':')
@ -171,7 +171,7 @@ inet_pton6(src, dst)
colonp = tp; colonp = tp;
continue; continue;
} }
if (tp + INT16SZ > endp) if (tp + NS_INT16SZ > endp)
return (0); return (0);
*tp++ = (u_char) (val >> 8) & 0xff; *tp++ = (u_char) (val >> 8) & 0xff;
*tp++ = (u_char) val & 0xff; *tp++ = (u_char) val & 0xff;
@ -179,16 +179,16 @@ inet_pton6(src, dst)
val = 0; val = 0;
continue; continue;
} }
if (ch == '.' && ((tp + INADDRSZ) <= endp) && if (ch == '.' && ((tp + NS_INADDRSZ) <= endp) &&
inet_pton4(curtok, tp) > 0) { inet_pton4(curtok, tp) > 0) {
tp += INADDRSZ; tp += NS_INADDRSZ;
saw_xdigit = 0; saw_xdigit = 0;
break; /* '\0' was seen by inet_pton4(). */ break; /* '\0' was seen by inet_pton4(). */
} }
return (0); return (0);
} }
if (saw_xdigit) { if (saw_xdigit) {
if (tp + INT16SZ > endp) if (tp + NS_INT16SZ > endp)
return (0); return (0);
*tp++ = (u_char) (val >> 8) & 0xff; *tp++ = (u_char) (val >> 8) & 0xff;
*tp++ = (u_char) val & 0xff; *tp++ = (u_char) val & 0xff;
@ -209,6 +209,6 @@ inet_pton6(src, dst)
} }
if (tp != endp) if (tp != endp)
return (0); return (0);
memcpy(dst, tmp, IN6ADDRSZ); memcpy(dst, tmp, NS_IN6ADDRSZ);
return (1); return (1);
} }

593
lib/libc/net/ns_name.c Normal file
View File

@ -0,0 +1,593 @@
/*
* Copyright (c) 1996 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.
*/
#ifndef lint
static char rcsid[] = "$Id: ns_name.c,v 8.3 1997/04/24 22:10:54 vixie Exp $";
#endif
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/nameser.h>
#include <errno.h>
#include <resolv.h>
#include <string.h>
/* Data. */
static char digits[] = "0123456789";
/* Forward. */
static int special(int);
static int printable(int);
static int dn_find(const u_char *, const u_char *,
const u_char * const *,
const u_char * const *);
/* Public. */
/*
* ns_name_ntop(src, dst, dstsiz)
* Convert an encoded domain name to printable ascii as per RFC1035.
* return:
* Number of bytes written to buffer, or -1 (with errno set)
* notes:
* The root is returned as "."
* All other domains are returned in non absolute form
*/
int
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;
cp = src;
dn = dst;
eom = dst + dstsiz;
while ((n = *cp++) != 0) {
if ((n & NS_CMPRSFLGS) != 0) {
/* Some kind of compression pointer. */
errno = EMSGSIZE;
return (-1);
}
if (dn != dst) {
if (dn >= eom) {
errno = EMSGSIZE;
return (-1);
}
*dn++ = '.';
}
if (dn + n >= eom) {
errno = EMSGSIZE;
return (-1);
}
for ((void)NULL; n > 0; n--) {
c = *cp++;
if (special(c)) {
if (dn + 1 >= eom) {
errno = EMSGSIZE;
return (-1);
}
*dn++ = '\\';
*dn++ = (char)c;
} else if (!printable(c)) {
if (dn + 3 >= eom) {
errno = EMSGSIZE;
return (-1);
}
*dn++ = '\\';
*dn++ = digits[c / 100];
*dn++ = digits[(c % 100) / 10];
*dn++ = digits[c % 10];
} else {
if (dn >= eom) {
errno = EMSGSIZE;
return (-1);
}
*dn++ = (char)c;
}
}
}
if (dn == dst) {
if (dn >= eom) {
errno = EMSGSIZE;
return (-1);
}
*dn++ = '.';
}
if (dn >= eom) {
errno = EMSGSIZE;
return (-1);
}
*dn++ = '\0';
return (dn - dst);
}
/*
* ns_name_pton(src, dst, dstsiz)
* Convert a ascii string into an encoded domain name as per RFC1035.
* return:
* -1 if it fails
* 1 if string was fully qualified
* 0 is string was not fully qualified
* notes:
* Enforces label and domain length limits.
*/
int
ns_name_pton(const char *src, u_char *dst, size_t dstsiz) {
u_char *label, *bp, *eom;
int c, n, escaped;
char *cp;
escaped = 0;
bp = dst;
eom = dst + dstsiz;
label = bp++;
while ((c = *src++) != 0) {
if (escaped) {
if ((cp = strchr(digits, c)) != NULL) {
n = (cp - digits) * 100;
if ((c = *src++) == 0 ||
(cp = strchr(digits, c)) == NULL) {
errno = EMSGSIZE;
return (-1);
}
n += (cp - digits) * 10;
if ((c = *src++) == 0 ||
(cp = strchr(digits, c)) == NULL) {
errno = EMSGSIZE;
return (-1);
}
n += (cp - digits);
if (n > 255) {
errno = EMSGSIZE;
return (-1);
}
c = n;
}
escaped = 0;
} else if (c == '\\') {
escaped = 1;
continue;
} else if (c == '.') {
c = (bp - label - 1);
if ((c & NS_CMPRSFLGS) != 0) { /* Label too big. */
errno = EMSGSIZE;
return (-1);
}
if (label >= eom) {
errno = EMSGSIZE;
return (-1);
}
*label = c;
/* Fully qualified ? */
if (*src == '\0') {
if (c != 0) {
if (bp >= eom) {
errno = EMSGSIZE;
return (-1);
}
*bp++ = '\0';
}
if ((bp - dst) > MAXCDNAME) {
errno = EMSGSIZE;
return (-1);
}
return (1);
}
if (c == 0) {
errno = EMSGSIZE;
return (-1);
}
label = bp++;
continue;
}
if (bp >= eom) {
errno = EMSGSIZE;
return (-1);
}
*bp++ = (u_char)c;
}
c = (bp - label - 1);
if ((c & NS_CMPRSFLGS) != 0) { /* Label too big. */
errno = EMSGSIZE;
return (-1);
}
if (label >= eom) {
errno = EMSGSIZE;
return (-1);
}
*label = c;
if (c != 0) {
if (bp >= eom) {
errno = EMSGSIZE;
return (-1);
}
*bp++ = 0;
}
if ((bp - dst) > MAXCDNAME) { /* src too big */
errno = EMSGSIZE;
return (-1);
}
return (0);
}
/*
* ns_name_unpack(msg, eom, src, dst, dstsiz)
* Unpack a domain name from a message, source may be compressed.
* return:
* -1 if it fails, or consumed octets if it succeeds.
*/
int
ns_name_unpack(const u_char *msg, const u_char *eom, const u_char *src,
u_char *dst, size_t dstsiz)
{
const u_char *srcp, *dstlim;
u_char *dstp;
int n, c, len, checked;
len = -1;
checked = 0;
dstp = dst;
srcp = src;
dstlim = dst + dstsiz;
if (srcp < msg || srcp >= eom) {
errno = EMSGSIZE;
return (-1);
}
/* Fetch next label in domain name. */
while ((n = *srcp++) != 0) {
/* Check for indirection. */
switch (n & NS_CMPRSFLGS) {
case 0:
/* Limit checks. */
if (dstp + n + 1 >= dstlim || srcp + n >= eom) {
errno = EMSGSIZE;
return (-1);
}
checked += n + 1;
*dstp++ = n;
memcpy(dstp, srcp, n);
dstp += n;
srcp += n;
break;
case NS_CMPRSFLGS:
if (srcp >= eom) {
errno = EMSGSIZE;
return (-1);
}
if (len < 0)
len = srcp - src + 1;
srcp = msg + (((n & 0x3f) << 8) | (*srcp & 0xff));
if (srcp < msg || srcp >= eom) { /* Out of range. */
errno = EMSGSIZE;
return (-1);
}
checked += 2;
/*
* Check for loops in the compressed name;
* if we've looked at the whole message,
* there must be a loop.
*/
if (checked >= eom - msg) {
errno = EMSGSIZE;
return (-1);
}
break;
default:
errno = EMSGSIZE;
return (-1); /* flag error */
}
}
*dstp = '\0';
if (len < 0)
len = srcp - src;
return (len);
}
/*
* ns_name_pack(src, dst, dstsiz, dnptrs, lastdnptr)
* Pack domain name 'domain' into 'comp_dn'.
* return:
* Size of the compressed name, or -1.
* notes:
* 'dnptrs' is an array of pointers to previous compressed names.
* dnptrs[0] is a pointer to the beginning of the message. The array
* ends with NULL.
* 'lastdnptr' is a pointer to the end of the array pointed to
* by 'dnptrs'.
* Side effects:
* The list of pointers in dnptrs is updated for labels inserted into
* the message as we compress the name. If 'dnptr' is NULL, we don't
* try to compress names. If 'lastdnptr' is NULL, we don't update the
* list.
*/
int
ns_name_pack(const u_char *src, u_char *dst, int dstsiz,
const u_char **dnptrs, const u_char **lastdnptr)
{
u_char *dstp;
const u_char **cpp, **lpp, *eob, *msg;
const u_char *srcp;
int n, l;
srcp = src;
dstp = dst;
eob = dstp + dstsiz;
lpp = cpp = NULL;
if (dnptrs != NULL) {
if ((msg = *dnptrs++) != NULL) {
for (cpp = dnptrs; *cpp != NULL; cpp++)
(void)NULL;
lpp = cpp; /* end of list to search */
}
} else
msg = NULL;
/* make sure the domain we are about to add is legal */
l = 0;
do {
n = *srcp;
if ((n & NS_CMPRSFLGS) != 0) {
errno = EMSGSIZE;
return (-1);
}
l += n + 1;
if (l > MAXCDNAME) {
errno = EMSGSIZE;
return (-1);
}
srcp += n + 1;
} while (n != 0);
srcp = src;
do {
/* Look to see if we can use pointers. */
n = *srcp;
if (n != 0 && msg != NULL) {
l = dn_find(srcp, msg, (const u_char * const *)dnptrs,
(const u_char * const *)lpp);
if (l >= 0) {
if (dstp + 1 >= eob) {
errno = EMSGSIZE;
return (-1);
}
*dstp++ = (l >> 8) | NS_CMPRSFLGS;
*dstp++ = l % 256;
return (dstp - dst);
}
/* Not found, save it. */
if (lastdnptr != NULL && cpp < lastdnptr - 1 &&
(dstp - msg) < 0x4000) {
*cpp++ = dstp;
*cpp = NULL;
}
}
/* copy label to buffer */
if (n & NS_CMPRSFLGS) { /* Should not happen. */
errno = EMSGSIZE;
return (-1);
}
if (dstp + 1 + n >= eob) {
errno = EMSGSIZE;
return (-1);
}
memcpy(dstp, srcp, n + 1);
srcp += n + 1;
dstp += n + 1;
} while (n != 0);
if (dstp > eob) {
if (msg != NULL)
*lpp = NULL;
errno = EMSGSIZE;
return (-1);
}
return (dstp - dst);
}
/*
* ns_name_uncompress(msg, eom, src, dst, dstsiz)
* Expand compressed domain name to presentation format.
* return:
* Number of bytes read out of `src', or -1 (with errno set).
* note:
* Root domain returns as "." not "".
*/
int
ns_name_uncompress(const u_char *msg, const u_char *eom, const u_char *src,
char *dst, size_t dstsiz)
{
u_char tmp[NS_MAXCDNAME];
int n;
if ((n = ns_name_unpack(msg, eom, src, tmp, sizeof tmp)) == -1)
return (-1);
if (ns_name_ntop(tmp, dst, dstsiz) == -1)
return (-1);
return (n);
}
/*
* ns_name_compress(src, dst, dstsiz, dnptrs, lastdnptr)
* Compress a domain name into wire format, using compression pointers.
* return:
* Number of bytes consumed in `dst' or -1 (with errno set).
* notes:
* 'dnptrs' is an array of pointers to previous compressed names.
* dnptrs[0] is a pointer to the beginning of the message.
* The list ends with NULL. 'lastdnptr' is a pointer to the end of the
* array pointed to by 'dnptrs'. Side effect is to update the list of
* pointers for labels inserted into the message as we compress the name.
* If 'dnptr' is NULL, we don't try to compress names. If 'lastdnptr'
* is NULL, we don't update the list.
*/
int
ns_name_compress(const char *src, u_char *dst, size_t dstsiz,
const u_char **dnptrs, const u_char **lastdnptr)
{
u_char tmp[NS_MAXCDNAME];
if (ns_name_pton(src, tmp, sizeof tmp) == -1)
return (-1);
return (ns_name_pack(tmp, dst, dstsiz, dnptrs, lastdnptr));
}
/*
* ns_name_skip(ptrptr, eom)
* Advance *ptrptr to skip over the compressed name it points at.
* return:
* 0 on success, -1 (with errno set) on failure.
*/
int
ns_name_skip(const u_char **ptrptr, const u_char *eom) {
const u_char *cp;
u_int n;
cp = *ptrptr;
while (cp < eom && (n = *cp++) != 0) {
/* Check for indirection. */
switch (n & NS_CMPRSFLGS) {
case 0: /* normal case, n == len */
cp += n;
continue;
case NS_CMPRSFLGS: /* indirection */
cp++;
break;
default: /* illegal type */
errno = EMSGSIZE;
return (-1);
}
break;
}
if (cp > eom) {
errno = EMSGSIZE;
return (-1);
}
*ptrptr = cp;
return (0);
}
/* Private. */
/*
* special(ch)
* Thinking in noninternationalized USASCII (per the DNS spec),
* is this characted special ("in need of quoting") ?
* return:
* boolean.
*/
static int
special(int ch) {
switch (ch) {
case 0x22: /* '"' */
case 0x2E: /* '.' */
case 0x3B: /* ';' */
case 0x5C: /* '\\' */
/* Special modifiers in zone files. */
case 0x40: /* '@' */
case 0x24: /* '$' */
return (1);
default:
return (0);
}
}
/*
* printable(ch)
* Thinking in noninternationalized USASCII (per the DNS spec),
* is this character visible and not a space when printed ?
* return:
* boolean.
*/
static int
printable(int ch) {
return (ch > 0x20 && ch < 0x7f);
}
/*
* Thinking in noninternationalized USASCII (per the DNS spec),
* convert this character to lower case if it's upper case.
*/
static int
mklower(int ch) {
if (ch >= 0x41 && ch <= 0x5A)
return (ch + 0x20);
return (ch);
}
/*
* dn_find(domain, msg, dnptrs, lastdnptr)
* Search for the counted-label name in an array of compressed names.
* return:
* offset from msg if found, or -1.
* notes:
* dnptrs is the pointer to the first name on the list,
* not the pointer to the start of the message.
*/
static int
dn_find(const u_char *domain, const u_char *msg,
const u_char * const *dnptrs,
const u_char * const *lastdnptr)
{
const u_char *dn, *cp, *sp;
const u_char * const *cpp;
u_int n;
for (cpp = dnptrs; cpp < lastdnptr; cpp++) {
dn = domain;
sp = cp = *cpp;
while ((n = *cp++) != 0) {
/*
* check for indirection
*/
switch (n & NS_CMPRSFLGS) {
case 0: /* normal case, n == len */
if (n != *dn++)
goto next;
for ((void)NULL; n > 0; n--)
if (mklower(*dn++) != mklower(*cp++))
goto next;
/* Is next root for both ? */
if (*dn == '\0' && *cp == '\0')
return (sp - msg);
if (*dn)
continue;
goto next;
case NS_CMPRSFLGS: /* indirection */
cp = msg + (((n & 0x3f) << 8) | *cp);
break;
default: /* illegal type */
errno = EMSGSIZE;
return (-1);
}
}
next: ;
}
errno = ENOENT;
return (-1);
}

54
lib/libc/net/ns_netint.c Normal file
View File

@ -0,0 +1,54 @@
/*
* Copyright (c) 1996 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.
*/
#ifndef lint
static char rcsid[] = "$Id: ns_netint.c,v 8.1 1996/11/18 09:09:57 vixie Exp $";
#endif
/* Import. */
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/nameser.h>
u_int
ns_get16(const u_char *src) {
u_int dst;
NS_GET16(dst, src);
return (dst);
}
u_long
ns_get32(const u_char *src) {
u_long dst;
NS_GET32(dst, src);
return (dst);
}
void
ns_put16(u_int src, u_char *dst) {
NS_PUT16(src, dst);
}
void
ns_put32(u_long src, u_char *dst) {
NS_PUT32(src, dst);
}

190
lib/libc/net/ns_parse.c Normal file
View File

@ -0,0 +1,190 @@
/*
* Copyright (c) 1996 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.
*/
#ifndef lint
static char rcsid[] = "$Id: ns_parse.c,v 8.8 1998/02/17 17:20:33 vixie Exp $";
#endif
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/nameser.h>
#include <errno.h>
#include <resolv.h>
#include <string.h>
/* These need to be in the same order as the nres.h:ns_flag enum. */
struct _ns_flagdata _ns_flagdata[16] = {
{ 0x8000, 15 }, /* qr. */
{ 0x7800, 11 }, /* opcode. */
{ 0x0400, 10 }, /* aa. */
{ 0x0200, 9 }, /* tc. */
{ 0x0100, 8 }, /* rd. */
{ 0x0080, 7 }, /* ra. */
{ 0x0040, 6 }, /* z. */
{ 0x0020, 5 }, /* ad. */
{ 0x0010, 4 }, /* cd. */
{ 0x000f, 0 }, /* rcode. */
{ 0x0000, 0 }, /* expansion (1/6). */
{ 0x0000, 0 }, /* expansion (2/6). */
{ 0x0000, 0 }, /* expansion (3/6). */
{ 0x0000, 0 }, /* expansion (4/6). */
{ 0x0000, 0 }, /* expansion (5/6). */
{ 0x0000, 0 }, /* expansion (6/6). */
};
static int
skiprr(const u_char *ptr, const u_char *eom, ns_sect section, int count) {
const u_char *optr = ptr;
for ((void)NULL; count > 0; count--) {
int b, rdlength;
b = dn_skipname(ptr, eom);
if (b < 0)
goto emsgsize;
ptr += b/*Name*/ + NS_INT16SZ/*Type*/ + NS_INT16SZ/*Class*/;
if (section != ns_s_qd) {
if (ptr + NS_INT32SZ > eom)
goto emsgsize;
ptr += NS_INT32SZ/*TTL*/;
if (ptr + NS_INT16SZ > eom)
goto emsgsize;
NS_GET16(rdlength, ptr);
ptr += rdlength/*RData*/;
}
}
if (ptr > eom)
goto emsgsize;
return (ptr - optr);
emsgsize:
errno = EMSGSIZE;
return (-1);
}
int
ns_initparse(const u_char *msg, int msglen, ns_msg *handle) {
const u_char *eom = msg + msglen;
int i;
memset(handle, 0x5e, sizeof *handle);
handle->_msg = msg;
handle->_eom = eom;
if (msg + NS_INT16SZ > eom)
goto emsgsize;
NS_GET16(handle->_id, msg);
if (msg + NS_INT16SZ > eom)
goto emsgsize;
NS_GET16(handle->_flags, msg);
for (i = 0; i < ns_s_max; i++) {
if (msg + NS_INT16SZ > eom)
goto emsgsize;
NS_GET16(handle->_counts[i], msg);
}
for (i = 0; i < ns_s_max; i++)
if (handle->_counts[i] == 0)
handle->_sections[i] = NULL;
else {
int b = skiprr(msg, eom, (ns_sect)i,
handle->_counts[i]);
if (b < 0)
return (-1);
handle->_sections[i] = msg;
msg += b;
}
if (msg != eom)
goto emsgsize;
handle->_sect = ns_s_max;
handle->_rrnum = -1;
handle->_ptr = NULL;
return (0);
emsgsize:
errno = EMSGSIZE;
return (-1);
}
int
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)
goto enodev;
if ((int)section != (int)handle->_sect) {
handle->_sect = section;
handle->_rrnum = 0;
handle->_ptr = handle->_sections[(int)section];
}
/* Make rrnum right. */
if (rrnum == -1)
rrnum = handle->_rrnum;
if (rrnum < 0 || rrnum >= handle->_counts[(int)section])
goto enodev;
if (rrnum < handle->_rrnum) {
handle->_rrnum = 0;
handle->_ptr = handle->_sections[(int)section];
}
b = skiprr(handle->_msg, handle->_eom, section,
rrnum - handle->_rrnum);
if (b < 0)
return (-1);
handle->_ptr += b;
handle->_rrnum = rrnum;
/* Do the parse. */
b = dn_expand(handle->_msg, handle->_eom,
handle->_ptr, rr->name, NS_MAXDNAME);
if (b < 0)
return (-1);
handle->_ptr += b;
if (handle->_ptr + NS_INT16SZ > handle->_eom)
goto emsgsize;
NS_GET16(rr->type, handle->_ptr);
if (handle->_ptr + NS_INT16SZ > handle->_eom)
goto emsgsize;
NS_GET16(rr->class, handle->_ptr);
if (section == ns_s_qd) {
rr->ttl = 0;
rr->rdlength = 0;
rr->rdata = NULL;
} else {
if (handle->_ptr + NS_INT32SZ > handle->_eom)
goto emsgsize;
NS_GET32(rr->ttl, handle->_ptr);
if (handle->_ptr + NS_INT16SZ > handle->_eom)
goto emsgsize;
NS_GET16(rr->rdlength, handle->_ptr);
if (handle->_ptr + rr->rdlength > handle->_eom)
goto emsgsize;
rr->rdata = handle->_ptr;
handle->_ptr += rr->rdlength;
}
handle->_rrnum++;
/* All done. */
return (0);
enodev:
errno = ENODEV;
return (-1);
emsgsize:
errno = EMSGSIZE;
return (-1);
}

743
lib/libc/net/ns_print.c Normal file
View File

@ -0,0 +1,743 @@
/*
* Copyright (c) 1996, 1998 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.
*/
#ifndef lint
static char rcsid[] = "$Id: ns_print.c,v 8.4 1998/02/13 01:16:37 halley Exp $";
#endif
/* Import. */
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/nameser.h>
#include <arpa/inet.h>
#include <assert.h>
#include <errno.h>
#include <resolv.h>
#include <string.h>
#include <ctype.h>
#define SPRINTF(x) ((size_t)sprintf x)
/* Forward. */
static size_t prune_origin(const char *name, const char *origin);
static int charstr(const u_char *rdata, const u_char *edata,
char **buf, size_t *buflen);
static int addname(const u_char *msg, size_t msglen,
const u_char **p, const char *origin,
char **buf, size_t *buflen);
static void addlen(size_t len, char **buf, size_t *buflen);
static int addstr(const char *src, size_t len,
char **buf, size_t *buflen);
static int addtab(size_t len, size_t target, int spaced,
char **buf, size_t *buflen);
/* Macros. */
#define T(x) \
do { \
if ((x) < 0) \
return (-1); \
} while (0)
/* Public. */
/*
* int
* ns_sprintrr(handle, rr, name_ctx, origin, buf, buflen)
* Convert an RR to presentation format.
* return:
* Number of characters written to buf, or -1 (check errno).
*/
int
ns_sprintrr(const ns_msg *handle, const ns_rr *rr,
const char *name_ctx, const char *origin,
char *buf, size_t buflen)
{
int n;
n = ns_sprintrrf(ns_msg_base(*handle), ns_msg_size(*handle),
ns_rr_name(*rr), ns_rr_class(*rr), ns_rr_type(*rr),
ns_rr_ttl(*rr), ns_rr_rdata(*rr), ns_rr_rdlen(*rr),
name_ctx, origin, buf, buflen);
return (n);
}
/*
* int
* ns_sprintrrf(msg, msglen, name, class, type, ttl, rdata, rdlen,
* name_ctx, origin, buf, buflen)
* Convert the fields of an RR into presentation format.
* return:
* Number of characters written to buf, or -1 (check errno).
*/
int
ns_sprintrrf(const u_char *msg, size_t msglen,
const char *name, ns_class class, ns_type type,
u_long ttl, const u_char *rdata, size_t rdlen,
const char *name_ctx, const char *origin,
char *buf, size_t buflen)
{
const char *obuf = buf;
const u_char *edata = rdata + rdlen;
int spaced = 0;
const char *comment;
char tmp[100];
int len, x;
/*
* Owner.
*/
if (name_ctx != NULL && strcasecmp(name_ctx, name) == 0) {
T(addstr("\t\t\t", 3, &buf, &buflen));
} else {
len = prune_origin(name, origin);
if (len == 0) {
T(addstr("@\t\t\t", 4, &buf, &buflen));
} else {
T(addstr(name, len, &buf, &buflen));
/* Origin not used and no trailing dot? */
if ((!origin || !origin[0] || name[len] == '\0') &&
name[len - 1] != '.') {
T(addstr(".", 1, &buf, &buflen));
len++;
}
T(spaced = addtab(len, 24, spaced, &buf, &buflen));
}
}
/*
* TTL, Class, Type.
*/
T(x = ns_format_ttl(ttl, buf, buflen));
addlen(x, &buf, &buflen);
len = SPRINTF((tmp, " %s %s", p_class(class), p_type(type)));
T(addstr(tmp, len, &buf, &buflen));
T(spaced = addtab(x + len, 16, spaced, &buf, &buflen));
/*
* RData.
*/
switch (type) {
case ns_t_a:
if (rdlen != NS_INADDRSZ)
goto formerr;
(void) inet_ntop(AF_INET, rdata, buf, buflen);
addlen(strlen(buf), &buf, &buflen);
break;
case ns_t_cname:
case ns_t_mb:
case ns_t_mg:
case ns_t_mr:
case ns_t_ns:
case ns_t_ptr:
T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
break;
case ns_t_hinfo:
case ns_t_isdn:
/* First word. */
T(len = charstr(rdata, edata, &buf, &buflen));
if (len == 0)
goto formerr;
rdata += len;
T(addstr(" ", 1, &buf, &buflen));
/* Second word. */
T(len = charstr(rdata, edata, &buf, &buflen));
if (len == 0)
goto formerr;
rdata += len;
break;
case ns_t_soa: {
u_long t;
/* Server name. */
T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
T(addstr(" ", 1, &buf, &buflen));
/* Administrator name. */
T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
T(addstr(" (\n", 3, &buf, &buflen));
spaced = 0;
if ((edata - rdata) != 5*NS_INT32SZ)
goto formerr;
/* Serial number. */
t = ns_get32(rdata); rdata += NS_INT32SZ;
T(addstr("\t\t\t\t\t", 5, &buf, &buflen));
len = SPRINTF((tmp, "%lu", t));
T(addstr(tmp, len, &buf, &buflen));
T(spaced = addtab(len, 16, spaced, &buf, &buflen));
T(addstr("; serial\n", 9, &buf, &buflen));
spaced = 0;
/* Refresh interval. */
t = ns_get32(rdata); rdata += NS_INT32SZ;
T(addstr("\t\t\t\t\t", 5, &buf, &buflen));
T(len = ns_format_ttl(t, buf, buflen));
addlen(len, &buf, &buflen);
T(spaced = addtab(len, 16, spaced, &buf, &buflen));
T(addstr("; refresh\n", 10, &buf, &buflen));
spaced = 0;
/* Retry interval. */
t = ns_get32(rdata); rdata += NS_INT32SZ;
T(addstr("\t\t\t\t\t", 5, &buf, &buflen));
T(len = ns_format_ttl(t, buf, buflen));
addlen(len, &buf, &buflen);
T(spaced = addtab(len, 16, spaced, &buf, &buflen));
T(addstr("; retry\n", 8, &buf, &buflen));
spaced = 0;
/* Expiry. */
t = ns_get32(rdata); rdata += NS_INT32SZ;
T(addstr("\t\t\t\t\t", 5, &buf, &buflen));
T(len = ns_format_ttl(t, buf, buflen));
addlen(len, &buf, &buflen);
T(spaced = addtab(len, 16, spaced, &buf, &buflen));
T(addstr("; expiry\n", 9, &buf, &buflen));
spaced = 0;
/* Minimum TTL. */
t = ns_get32(rdata); rdata += NS_INT32SZ;
T(addstr("\t\t\t\t\t", 5, &buf, &buflen));
T(len = ns_format_ttl(t, buf, buflen));
addlen(len, &buf, &buflen);
T(addstr(" )", 2, &buf, &buflen));
T(spaced = addtab(len, 16, spaced, &buf, &buflen));
T(addstr("; minimum\n", 10, &buf, &buflen));
break;
}
case ns_t_mx:
case ns_t_afsdb:
case ns_t_rt: {
u_int t;
if (rdlen < NS_INT16SZ)
goto formerr;
/* Priority. */
t = ns_get16(rdata);
rdata += NS_INT16SZ;
len = SPRINTF((tmp, "%u ", t));
T(addstr(tmp, len, &buf, &buflen));
/* Target. */
T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
break;
}
case ns_t_px: {
u_int t;
if (rdlen < NS_INT16SZ)
goto formerr;
/* Priority. */
t = ns_get16(rdata);
rdata += NS_INT16SZ;
len = SPRINTF((tmp, "%u ", t));
T(addstr(tmp, len, &buf, &buflen));
/* Name1. */
T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
T(addstr(" ", 1, &buf, &buflen));
/* Name2. */
T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
break;
}
case ns_t_x25:
T(len = charstr(rdata, edata, &buf, &buflen));
if (len == 0)
goto formerr;
rdata += len;
break;
case ns_t_txt:
while (rdata < edata) {
T(len = charstr(rdata, edata, &buf, &buflen));
if (len == 0)
goto formerr;
rdata += len;
if (rdata < edata)
T(addstr(" ", 1, &buf, &buflen));
}
break;
case ns_t_nsap: {
char t[255*3];
(void) inet_nsap_ntoa(rdlen, rdata, t);
T(addstr(t, strlen(t), &buf, &buflen));
break;
}
case ns_t_aaaa:
if (rdlen != NS_IN6ADDRSZ)
goto formerr;
(void) inet_ntop(AF_INET6, rdata, buf, buflen);
addlen(strlen(buf), &buf, &buflen);
break;
case ns_t_loc: {
char t[255];
/* XXX protocol format checking? */
(void) loc_ntoa(rdata, t);
T(addstr(t, strlen(t), &buf, &buflen));
break;
}
case ns_t_naptr: {
u_int order, preference;
char t[50];
if (rdlen < 2*NS_INT16SZ)
goto formerr;
/* Order, Precedence. */
order = ns_get16(rdata); rdata += NS_INT16SZ;
preference = ns_get16(rdata); rdata += NS_INT16SZ;
len = SPRINTF((t, "%u %u ", order, preference));
T(addstr(t, len, &buf, &buflen));
/* Flags. */
T(len = charstr(rdata, edata, &buf, &buflen));
if (len == 0)
goto formerr;
rdata += len;
T(addstr(" ", 1, &buf, &buflen));
/* Service. */
T(len = charstr(rdata, edata, &buf, &buflen));
if (len == 0)
goto formerr;
rdata += len;
T(addstr(" ", 1, &buf, &buflen));
/* Regexp. */
T(len = charstr(rdata, edata, &buf, &buflen));
if (len < 0)
return (-1);
if (len == 0)
goto formerr;
rdata += len;
T(addstr(" ", 1, &buf, &buflen));
/* Server. */
T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
break;
}
case ns_t_srv: {
u_int priority, weight, port;
char t[50];
if (rdlen < NS_INT16SZ*3)
goto formerr;
/* Priority, Weight, Port. */
priority = ns_get16(rdata); rdata += NS_INT16SZ;
weight = ns_get16(rdata); rdata += NS_INT16SZ;
port = ns_get16(rdata); rdata += NS_INT16SZ;
len = SPRINTF((t, "%u %u %u ", priority, weight, port));
T(addstr(t, len, &buf, &buflen));
/* Server. */
T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
break;
}
case ns_t_minfo:
case ns_t_rp:
/* Name1. */
T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
T(addstr(" ", 1, &buf, &buflen));
/* Name2. */
T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
break;
case ns_t_wks: {
int n, lcnt;
if (rdlen < NS_INT32SZ + 1)
goto formerr;
/* Address. */
(void) inet_ntop(AF_INET, rdata, buf, buflen);
addlen(strlen(buf), &buf, &buflen);
rdata += NS_INADDRSZ;
/* Protocol. */
len = SPRINTF((tmp, " %u ( ", *rdata));
T(addstr(tmp, len, &buf, &buflen));
rdata += NS_INT8SZ;
/* Bit map. */
n = 0;
lcnt = 0;
while (rdata < edata) {
u_int c = *rdata++;
do {
if (c & 0200) {
if (lcnt == 0) {
T(addstr("\n\t\t\t\t", 5,
&buf, &buflen));
lcnt = 10;
spaced = 0;
}
len = SPRINTF((tmp, "%d ", n));
T(addstr(tmp, len, &buf, &buflen));
lcnt--;
}
c <<= 1;
} while (++n & 07);
}
T(addstr(")", 1, &buf, &buflen));
break;
}
case ns_t_key: {
char base64_key[NS_MD5RSA_MAX_BASE64];
u_int keyflags, protocol, algorithm;
const char *leader;
int n;
if (rdlen < NS_INT16SZ + NS_INT8SZ + NS_INT8SZ)
goto formerr;
/* Key flags, Protocol, Algorithm. */
keyflags = ns_get16(rdata); rdata += NS_INT16SZ;
protocol = *rdata++;
algorithm = *rdata++;
len = SPRINTF((tmp, "0x%04x %u %u",
keyflags, protocol, algorithm));
T(addstr(tmp, len, &buf, &buflen));
/* Public key data. */
len = b64_ntop(rdata, edata - rdata,
base64_key, sizeof base64_key);
if (len < 0)
goto formerr;
if (len > 15) {
T(addstr(" (", 2, &buf, &buflen));
leader = "\n\t\t";
spaced = 0;
} else
leader = " ";
for (n = 0; n < len; n += 48) {
T(addstr(leader, strlen(leader), &buf, &buflen));
T(addstr(base64_key + n, MIN(len - n, 48),
&buf, &buflen));
}
if (len > 15)
T(addstr(" )", 2, &buf, &buflen));
break;
}
case ns_t_sig: {
char base64_key[NS_MD5RSA_MAX_BASE64];
u_int type, algorithm, labels, footprint;
const char *leader;
u_long t;
int n;
if (rdlen < 22)
goto formerr;
/* Type covered, Algorithm, Label count, Original TTL. */
type = ns_get16(rdata); rdata += NS_INT16SZ;
algorithm = *rdata++;
labels = *rdata++;
t = ns_get32(rdata); rdata += NS_INT32SZ;
len = SPRINTF((tmp, " %s %d %lu ",
p_type(type), algorithm, t));
T(addstr(tmp, len, &buf, &buflen));
if (labels != (u_int)dn_count_labels(name))
goto formerr;
/* Signature expiry. */
t = ns_get32(rdata); rdata += NS_INT32SZ;
len = SPRINTF((tmp, "%s ", p_secstodate(t)));
T(addstr(tmp, len, &buf, &buflen));
/* Time signed. */
t = ns_get32(rdata); rdata += NS_INT32SZ;
len = SPRINTF((tmp, "%s ", p_secstodate(t)));
T(addstr(tmp, len, &buf, &buflen));
/* Signature Footprint. */
footprint = ns_get16(rdata); rdata += NS_INT16SZ;
len = SPRINTF((tmp, "%u ", footprint));
T(addstr(tmp, len, &buf, &buflen));
/* Signer's name. */
T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
/* Signature. */
len = b64_ntop(rdata, edata - rdata,
base64_key, sizeof base64_key);
if (len > 15) {
T(addstr(" (", 2, &buf, &buflen));
leader = "\n\t\t";
spaced = 0;
} else
leader = " ";
if (len < 0)
goto formerr;
for (n = 0; n < len; n += 48) {
T(addstr(leader, strlen(leader), &buf, &buflen));
T(addstr(base64_key + n, MIN(len - n, 48),
&buf, &buflen));
}
if (len > 15)
T(addstr(" )", 2, &buf, &buflen));
break;
}
case ns_t_nxt: {
int n, c;
/* Next domain name. */
T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
/* Type bit map. */
n = edata - rdata;
for (c = 0; c < n*8; c++)
if (NS_NXT_BIT_ISSET(c, rdata)) {
len = SPRINTF((tmp, " %s", p_type(c)));
T(addstr(tmp, len, &buf, &buflen));
}
break;
}
default:
comment = "unknown RR type";
goto hexify;
}
return (buf - obuf);
formerr:
comment = "RR format error";
hexify: {
int n, m;
char *p;
len = SPRINTF((tmp, "\\#(\t\t; %s", comment));
T(addstr(tmp, len, &buf, &buflen));
while (rdata < edata) {
p = tmp;
p += SPRINTF((p, "\n\t"));
spaced = 0;
n = MIN(16, edata - rdata);
for (m = 0; m < n; m++)
p += SPRINTF((p, "%02x ", rdata[m]));
T(addstr(tmp, p - tmp, &buf, &buflen));
if (n < 16) {
T(addstr(")", 1, &buf, &buflen));
T(addtab(p - tmp + 1, 48, spaced, &buf, &buflen));
}
p = tmp;
p += SPRINTF((p, "; "));
for (m = 0; m < n; m++)
*p++ = (isascii(rdata[m]) && isprint(rdata[m]))
? rdata[m]
: '.';
T(addstr(tmp, p - tmp, &buf, &buflen));
rdata += n;
}
return (buf - obuf);
}
}
/* Private. */
/*
* size_t
* prune_origin(name, origin)
* Find out if the name is at or under the current origin.
* return:
* Number of characters in name before start of origin,
* or length of name if origin does not match.
* notes:
* This function should share code with samedomain().
*/
static size_t
prune_origin(const char *name, const char *origin) {
const char *oname = name;
while (*name != '\0') {
if (origin != NULL && strcasecmp(name, origin) == 0)
return (name - oname - (name > oname));
while (*name != '\0') {
if (*name == '\\') {
name++;
/* XXX need to handle \nnn form. */
if (*name == '\0')
break;
} else if (*name == '.') {
name++;
break;
}
name++;
}
}
return (name - oname);
}
/*
* int
* charstr(rdata, edata, buf, buflen)
* Format a <character-string> into the presentation buffer.
* return:
* Number of rdata octets consumed
* 0 for protocol format error
* -1 for output buffer error
* side effects:
* buffer is advanced on success.
*/
static int
charstr(const u_char *rdata, const u_char *edata, char **buf, size_t *buflen) {
const u_char *odata = rdata;
size_t save_buflen = *buflen;
char *save_buf = *buf;
if (addstr("\"", 1, buf, buflen) < 0)
goto enospc;
if (rdata < edata) {
int n = *rdata;
if (rdata + 1 + n <= edata) {
rdata++;
while (n-- > 0) {
if (strchr("\n\"\\", *rdata) != NULL)
if (addstr("\\", 1, buf, buflen) < 0)
goto enospc;
if (addstr((const char *)rdata, 1,
buf, buflen) < 0)
goto enospc;
rdata++;
}
}
}
if (addstr("\"", 1, buf, buflen) < 0)
goto enospc;
return (rdata - odata);
enospc:
errno = ENOSPC;
*buf = save_buf;
*buflen = save_buflen;
return (-1);
}
static int
addname(const u_char *msg, size_t msglen,
const u_char **pp, const char *origin,
char **buf, size_t *buflen)
{
size_t newlen, save_buflen = *buflen;
char *save_buf = *buf;
int n;
n = dn_expand(msg, msg + msglen, *pp, *buf, *buflen);
if (n < 0)
goto enospc; /* Guess. */
newlen = prune_origin(*buf, origin);
if ((origin == NULL || origin[0] == '\0' || (*buf)[newlen] == '\0') &&
(newlen == 0 || (*buf)[newlen - 1] != '.')) {
/* No trailing dot. */
if (newlen + 2 > *buflen)
goto enospc; /* No room for ".\0". */
(*buf)[newlen++] = '.';
(*buf)[newlen] = '\0';
}
if (newlen == 0) {
/* Use "@" instead of name. */
if (newlen + 2 > *buflen)
goto enospc; /* No room for "@\0". */
(*buf)[newlen++] = '@';
(*buf)[newlen] = '\0';
}
*pp += n;
addlen(newlen, buf, buflen);
**buf = '\0';
return (newlen);
enospc:
errno = ENOSPC;
*buf = save_buf;
*buflen = save_buflen;
return (-1);
}
static void
addlen(size_t len, char **buf, size_t *buflen) {
assert(len <= *buflen);
*buf += len;
*buflen -= len;
}
static int
addstr(const char *src, size_t len, char **buf, size_t *buflen) {
if (len > *buflen) {
errno = ENOSPC;
return (-1);
}
memcpy(*buf, src, len);
addlen(len, buf, buflen);
**buf = '\0';
return (0);
}
static int
addtab(size_t len, size_t target, int spaced, char **buf, size_t *buflen) {
size_t save_buflen = *buflen;
char *save_buf = *buf;
int t;
if (spaced || len >= target - 1) {
T(addstr(" ", 2, buf, buflen));
spaced = 1;
} else {
for (t = (target - len - 1) / 8; t >= 0; t--)
if (addstr("\t", 1, buf, buflen) < 0) {
*buflen = save_buflen;
*buf = save_buf;
return (-1);
}
spaced = 0;
}
return (spaced);
}

151
lib/libc/net/ns_ttl.c Normal file
View File

@ -0,0 +1,151 @@
/*
* Copyright (c) 1996 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.
*/
#ifndef lint
static char rcsid[] = "$Id: ns_ttl.c,v 8.5 1998/02/13 01:16:38 halley Exp $";
#endif
/* Import. */
#include <arpa/nameser.h>
#include <ctype.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>
#define SPRINTF(x) ((size_t)sprintf x)
/* Forward. */
static int fmt1(int t, char s, char **buf, size_t *buflen);
/* Macros. */
#define T(x) if ((x) < 0) return (-1); else (void)NULL
/* Public. */
int
ns_format_ttl(u_long src, char *dst, size_t dstlen) {
char *odst = dst;
int secs, mins, hours, days, weeks, x;
char tmp[50], *p;
secs = src % 60; src /= 60;
mins = src % 60; src /= 60;
hours = src % 24; src /= 24;
days = src % 7; src /= 7;
weeks = src; src = 0;
x = 0;
if (weeks) {
T(fmt1(weeks, 'W', &dst, &dstlen));
x++;
}
if (days) {
T(fmt1(days, 'D', &dst, &dstlen));
x++;
}
if (hours) {
T(fmt1(hours, 'H', &dst, &dstlen));
x++;
}
if (mins) {
T(fmt1(mins, 'M', &dst, &dstlen));
x++;
}
if (secs || !(weeks || days || hours || mins)) {
T(fmt1(secs, 'S', &dst, &dstlen));
x++;
}
if (x > 1) {
int ch;
for (p = odst; (ch = *p) != '\0'; p++)
if (isascii(ch) && isupper(ch))
*p = tolower(ch);
}
return (dst - odst);
}
int
ns_parse_ttl(const char *src, u_long *dst) {
u_long ttl, tmp;
int ch, digits, dirty;
ttl = 0;
tmp = 0;
digits = 0;
dirty = 0;
while ((ch = *src++) != '\0') {
if (!isascii(ch) || !isprint(ch))
goto einval;
if (isdigit(ch)) {
tmp *= 10;
tmp += (ch - '0');
digits++;
continue;
}
if (digits == 0)
goto einval;
if (islower(ch))
ch = toupper(ch);
switch (ch) {
case 'W': tmp *= 7;
case 'D': tmp *= 24;
case 'H': tmp *= 60;
case 'M': tmp *= 60;
case 'S': break;
default: goto einval;
}
ttl += tmp;
tmp = 0;
digits = 0;
dirty = 1;
}
if (digits > 0) {
if (dirty)
goto einval;
else
ttl += tmp;
}
*dst = ttl;
return (0);
einval:
errno = EINVAL;
return (-1);
}
/* Private. */
static int
fmt1(int t, char s, char **buf, size_t *buflen) {
char tmp[50];
size_t len;
len = SPRINTF((tmp, "%d%c", t, s));
if (len + 1 > *buflen)
return (-1);
strcpy(*buf, tmp);
*buf += len;
*buflen -= len;
return (0);
}

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1996 by Internet Software Consortium. * Copyright (c) 1996, 1998 by Internet Software Consortium.
* *
* Permission to use, copy, modify, and distribute this software for any * Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above * purpose with or without fee is hereby granted, provided that the above
@ -16,13 +16,14 @@
*/ */
#if defined(LIBC_SCCS) && !defined(lint) #if defined(LIBC_SCCS) && !defined(lint)
static char rcsid[] = "$Id$"; static char rcsid[] = "$Id: nsap_addr.c,v 1.4 1997/02/22 15:00:27 peter Exp $";
#endif /* LIBC_SCCS and not lint */ #endif /* LIBC_SCCS and not lint */
#include <sys/types.h> #include <sys/types.h>
#include <sys/param.h> #include <sys/param.h>
#include <sys/socket.h> #include <sys/socket.h>
#include <netinet/in.h> #include <netinet/in.h>
#include <arpa/inet.h>
#include <arpa/nameser.h> #include <arpa/nameser.h>
#include <ctype.h> #include <ctype.h>
#include <resolv.h> #include <resolv.h>
@ -40,10 +41,10 @@ inet_nsap_addr(ascii, binary, maxlen)
u_char *binary; u_char *binary;
int maxlen; int maxlen;
{ {
register u_char c, nib; u_char c, nib;
u_int len = 0; u_int len = 0;
while ((c = *ascii++) != '\0' && len < maxlen) { while ((c = *ascii++) != '\0' && len < (u_int)maxlen) {
if (c == '.' || c == '+' || c == '/') if (c == '.' || c == '+' || c == '/')
continue; continue;
if (!isascii(c)) if (!isascii(c))
@ -52,7 +53,8 @@ inet_nsap_addr(ascii, binary, maxlen)
c = toupper(c); c = toupper(c);
if (isxdigit(c)) { if (isxdigit(c)) {
nib = xtob(c); nib = xtob(c);
if ((c = *ascii++) != '\0') { c = *ascii++;
if (c != '\0') {
c = toupper(c); c = toupper(c);
if (isxdigit(c)) { if (isxdigit(c)) {
*binary++ = (nib << 4) | xtob(c); *binary++ = (nib << 4) | xtob(c);

View File

@ -1,6 +1,4 @@
/* /*
* ++Copyright++ 1985, 1993
* -
* Copyright (c) 1985, 1993 * Copyright (c) 1985, 1993
* The Regents of the University of California. All rights reserved. * The Regents of the University of California. All rights reserved.
* *
@ -31,7 +29,9 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * 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 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE. * SUCH DAMAGE.
* - */
/*
* Portions Copyright (c) 1993 by Digital Equipment Corporation. * Portions Copyright (c) 1993 by Digital Equipment Corporation.
* *
* Permission to use, copy, modify, and distribute this software for any * Permission to use, copy, modify, and distribute this software for any
@ -49,40 +49,42 @@
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS * 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 * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
* SOFTWARE. * SOFTWARE.
* - */
* --Copyright--
/*
* Portions Copyright (c) 1996 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) #if defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "@(#)res_comp.c 8.1 (Berkeley) 6/4/93"; static char sccsid[] = "@(#)res_comp.c 8.1 (Berkeley) 6/4/93";
static char orig_rcsid[] = "From: Id: res_comp.c,v 8.13 1998/04/07 04:24:06 vixie Exp $"; static char orig_rcsid[] = "From: Id: res_comp.c,v 8.11 1997/05/21 19:31:04 halley Exp $";
static char rcsid[] = "$Id: res_comp.c,v 1.12 1997/06/27 08:22:02 peter Exp $"; static char rcsid[] = "$Id: res_comp.c,v 1.13 1998/05/02 13:10:56 peter Exp $";
#endif /* LIBC_SCCS and not lint */ #endif /* LIBC_SCCS and not lint */
#include <sys/types.h> #include <sys/types.h>
#include <sys/param.h> #include <sys/param.h>
#include <netinet/in.h> #include <netinet/in.h>
#include <arpa/nameser.h> #include <arpa/nameser.h>
#include <stdio.h>
#include <resolv.h>
#include <ctype.h> #include <ctype.h>
#include <errno.h> #include <resolv.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h> #include <string.h>
#include <unistd.h>
static int ns_name_ntop __P((const u_char *, char *, size_t)); #define BIND_4_COMPAT
static int ns_name_pton __P((const char *, u_char *, size_t));
static int ns_name_unpack __P((const u_char *, const u_char *,
const u_char *, u_char *, size_t));
static int ns_name_pack __P((const u_char *, u_char *, int,
const u_char **, const u_char **));
static int ns_name_uncompress __P((const u_char *, const u_char *,
const u_char *, char *, size_t));
static int ns_name_compress __P((const char *, u_char *, size_t,
const u_char **, const u_char **));
static int ns_name_skip __P((const u_char **, const u_char *));
/* /*
* Expand compressed domain name 'comp_dn' to full domain name. * Expand compressed domain name 'comp_dn' to full domain name.
@ -120,7 +122,7 @@ dn_comp(const char *src, u_char *dst, int dstsiz,
* Skip over a compressed domain name. Return the size or -1. * Skip over a compressed domain name. Return the size or -1.
*/ */
int int
__dn_skipname(const u_char *ptr, const u_char *eom) { dn_skipname(const u_char *ptr, const u_char *eom) {
const u_char *saveptr = ptr; const u_char *saveptr = ptr;
if (ns_name_skip(&ptr, eom) == -1) if (ns_name_skip(&ptr, eom) == -1)
@ -161,7 +163,7 @@ res_hnok(dn)
int nch = *dn++; int nch = *dn++;
if (periodchar(ch)) { if (periodchar(ch)) {
NULL; (void)NULL;
} else if (periodchar(pch)) { } else if (periodchar(pch)) {
if (!borderchar(ch)) if (!borderchar(ch))
return (0); return (0);
@ -206,7 +208,7 @@ res_mailok(dn)
/* "." is a valid missing representation */ /* "." is a valid missing representation */
if (*dn == '\0') if (*dn == '\0')
return(1); return (1);
/* otherwise <label>.<hostname> */ /* otherwise <label>.<hostname> */
while ((ch = *dn++) != '\0') { while ((ch = *dn++) != '\0') {
@ -221,7 +223,7 @@ res_mailok(dn)
} }
if (periodchar(ch)) if (periodchar(ch))
return (res_hnok(dn)); return (res_hnok(dn));
return(0); return (0);
} }
/* /*
@ -240,683 +242,17 @@ res_dnok(dn)
return (1); return (1);
} }
#ifdef BIND_4_COMPAT
/* /*
* Routines to insert/extract short/long's. * This module must export the following externally-visible symbols:
* ___putlong
* ___putshort
* __getlong
* __getshort
* Note that one _ comes from C and the others come from us.
*/ */
void __putlong(u_int32_t src, u_char *dst) { ns_put32(src, dst); }
u_int16_t void __putshort(u_int16_t src, u_char *dst) { ns_put16(src, dst); }
_getshort(msgp) u_int32_t _getlong(const u_char *src) { return (ns_get32(src)); }
register const u_char *msgp; u_int16_t _getshort(const u_char *src) { return (ns_get16(src)); }
{ #endif /*BIND_4_COMPAT*/
register u_int16_t u;
GETSHORT(u, msgp);
return (u);
}
u_int32_t
_getlong(msgp)
register const u_char *msgp;
{
register u_int32_t u;
GETLONG(u, msgp);
return (u);
}
void
#if defined(__STDC__) || defined(__cplusplus)
__putshort(register u_int16_t s, register u_char *msgp) /* must match proto */
#else
__putshort(s, msgp)
register u_int16_t s;
register u_char *msgp;
#endif
{
PUTSHORT(s, msgp);
}
void
__putlong(l, msgp)
register u_int32_t l;
register u_char *msgp;
{
PUTLONG(l, msgp);
}
/* ++ From BIND 8.1.1. ++ */
/*
* Copyright (c) 1996 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.
*/
/*"Id: ns_name.c,v 1.1 1997/12/13 02:41:13 vixie Exp vixie"*/
/*#include "port_before.h"*/
/*#include <sys/types.h>*/
/*#include <netinet/in.h>*/
/*#include <arpa/nameser.h>*/
/*#include <errno.h>*/
/*#include <resolv.h>*/
/*#include <string.h>*/
/*#include "port_after.h"*/
#define NS_CMPRSFLGS 0xc0 /* Flag bits indicating name compression. */
#define NS_MAXCDNAME 255 /* maximum compressed domain name */
/* Data. */
static char digits[] = "0123456789";
/* Forward. */
static int special(int);
static int printable(int);
static int dn_find(const u_char *, const u_char *,
const u_char * const *,
const u_char * const *);
/* Public. */
/*
* ns_name_ntop(src, dst, dstsiz)
* Convert an encoded domain name to printable ascii as per RFC1035.
* return:
* Number of bytes written to buffer, or -1 (with errno set)
* notes:
* The root is returned as "."
* All other domains are returned in non absolute form
*/
static int
ns_name_ntop(src, dst, dstsiz)
const u_char *src;
char *dst;
size_t dstsiz;
{
const u_char *cp;
char *dn, *eom;
u_char c;
u_int n;
cp = src;
dn = dst;
eom = dst + dstsiz;
while ((n = *cp++) != 0) {
if ((n & NS_CMPRSFLGS) != 0) {
/* Some kind of compression pointer. */
errno = EMSGSIZE;
return (-1);
}
if (dn != dst) {
if (dn >= eom) {
errno = EMSGSIZE;
return (-1);
}
*dn++ = '.';
}
if (dn + n >= eom) {
errno = EMSGSIZE;
return (-1);
}
for ((void)NULL; n > 0; n--) {
c = *cp++;
if (special(c)) {
if (dn + 1 >= eom) {
errno = EMSGSIZE;
return (-1);
}
*dn++ = '\\';
*dn++ = (char)c;
} else if (!printable(c)) {
if (dn + 3 >= eom) {
errno = EMSGSIZE;
return (-1);
}
*dn++ = '\\';
*dn++ = digits[c / 100];
*dn++ = digits[(c % 100) / 10];
*dn++ = digits[c % 10];
} else {
if (dn >= eom) {
errno = EMSGSIZE;
return (-1);
}
*dn++ = (char)c;
}
}
}
if (dn == dst) {
if (dn >= eom) {
errno = EMSGSIZE;
return (-1);
}
*dn++ = '.';
}
if (dn >= eom) {
errno = EMSGSIZE;
return (-1);
}
*dn++ = '\0';
return (dn - dst);
}
/*
* ns_name_pton(src, dst, dstsiz)
* Convert a ascii string into an encoded domain name as per RFC1035.
* return:
* -1 if it fails
* 1 if string was fully qualified
* 0 is string was not fully qualified
* notes:
* Enforces label and domain length limits.
*/
static int
ns_name_pton(src, dst, dstsiz)
const char *src;
u_char *dst;
size_t dstsiz;
{
u_char *label, *bp, *eom;
int c, n, escaped;
char *cp;
escaped = 0;
bp = dst;
eom = dst + dstsiz;
label = bp++;
while ((c = *src++) != 0) {
if (escaped) {
if ((cp = strchr(digits, c)) != NULL) {
n = (cp - digits) * 100;
if ((c = *src++) == 0 ||
(cp = strchr(digits, c)) == NULL) {
errno = EMSGSIZE;
return (-1);
}
n += (cp - digits) * 10;
if ((c = *src++) == 0 ||
(cp = strchr(digits, c)) == NULL) {
errno = EMSGSIZE;
return (-1);
}
n += (cp - digits);
if (n > 255) {
errno = EMSGSIZE;
return (-1);
}
c = n;
}
escaped = 0;
} else if (c == '\\') {
escaped = 1;
continue;
} else if (c == '.') {
c = (bp - label - 1);
if ((c & NS_CMPRSFLGS) != 0) { /* Label too big. */
errno = EMSGSIZE;
return (-1);
}
if (label >= eom) {
errno = EMSGSIZE;
return (-1);
}
*label = c;
/* Fully qualified ? */
if (*src == '\0') {
if (c != 0) {
if (bp >= eom) {
errno = EMSGSIZE;
return (-1);
}
*bp++ = '\0';
}
if ((bp - dst) > MAXCDNAME) {
errno = EMSGSIZE;
return (-1);
}
return (1);
}
if (c == 0) {
errno = EMSGSIZE;
return (-1);
}
label = bp++;
continue;
}
if (bp >= eom) {
errno = EMSGSIZE;
return (-1);
}
*bp++ = (u_char)c;
}
c = (bp - label - 1);
if ((c & NS_CMPRSFLGS) != 0) { /* Label too big. */
errno = EMSGSIZE;
return (-1);
}
if (label >= eom) {
errno = EMSGSIZE;
return (-1);
}
*label = c;
if (c != 0) {
if (bp >= eom) {
errno = EMSGSIZE;
return (-1);
}
*bp++ = 0;
}
if ((bp - dst) > MAXCDNAME) { /* src too big */
errno = EMSGSIZE;
return (-1);
}
return (0);
}
/*
* ns_name_unpack(msg, eom, src, dst, dstsiz)
* Unpack a domain name from a message, source may be compressed.
* return:
* -1 if it fails, or consumed octets if it succeeds.
*/
static int
ns_name_unpack(msg, eom, src, dst, dstsiz)
const u_char *msg;
const u_char *eom;
const u_char *src;
u_char *dst;
size_t dstsiz;
{
const u_char *srcp, *dstlim;
u_char *dstp;
int n, c, len, checked;
len = -1;
checked = 0;
dstp = dst;
srcp = src;
dstlim = dst + dstsiz;
if (srcp < msg || srcp >= eom) {
errno = EMSGSIZE;
return (-1);
}
/* Fetch next label in domain name. */
while ((n = *srcp++) != 0) {
/* Check for indirection. */
switch (n & NS_CMPRSFLGS) {
case 0:
/* Limit checks. */
if (dstp + n + 1 >= dstlim || srcp + n >= eom) {
errno = EMSGSIZE;
return (-1);
}
checked += n + 1;
*dstp++ = n;
memcpy(dstp, srcp, n);
dstp += n;
srcp += n;
break;
case NS_CMPRSFLGS:
if (srcp >= eom) {
errno = EMSGSIZE;
return (-1);
}
if (len < 0)
len = srcp - src + 1;
srcp = msg + (((n & 0x3f) << 8) | (*srcp & 0xff));
if (srcp < msg || srcp >= eom) { /* Out of range. */
errno = EMSGSIZE;
return (-1);
}
checked += 2;
/*
* Check for loops in the compressed name;
* if we've looked at the whole message,
* there must be a loop.
*/
if (checked >= eom - msg) {
errno = EMSGSIZE;
return (-1);
}
break;
default:
errno = EMSGSIZE;
return (-1); /* flag error */
}
}
*dstp = '\0';
if (len < 0)
len = srcp - src;
return (len);
}
/*
* ns_name_pack(src, dst, dstsiz, dnptrs, lastdnptr)
* Pack domain name 'domain' into 'comp_dn'.
* return:
* Size of the compressed name, or -1.
* notes:
* 'dnptrs' is an array of pointers to previous compressed names.
* dnptrs[0] is a pointer to the beginning of the message. The array
* ends with NULL.
* 'lastdnptr' is a pointer to the end of the array pointed to
* by 'dnptrs'.
* Side effects:
* The list of pointers in dnptrs is updated for labels inserted into
* the message as we compress the name. If 'dnptr' is NULL, we don't
* try to compress names. If 'lastdnptr' is NULL, we don't update the
* list.
*/
static int
ns_name_pack(src, dst, dstsiz, dnptrs, lastdnptr)
const u_char *src;
u_char *dst;
int dstsiz;
const u_char **dnptrs;
const u_char **lastdnptr;
{
u_char *dstp;
const u_char **cpp, **lpp, *eob, *msg;
const u_char *srcp;
int n, l;
srcp = src;
dstp = dst;
eob = dstp + dstsiz;
lpp = cpp = NULL;
if (dnptrs != NULL) {
if ((msg = *dnptrs++) != NULL) {
for (cpp = dnptrs; *cpp != NULL; cpp++)
(void)NULL;
lpp = cpp; /* end of list to search */
}
} else
msg = NULL;
/* make sure the domain we are about to add is legal */
l = 0;
do {
n = *srcp;
if ((n & NS_CMPRSFLGS) != 0) {
errno = EMSGSIZE;
return (-1);
}
l += n + 1;
if (l > MAXCDNAME) {
errno = EMSGSIZE;
return (-1);
}
srcp += n + 1;
} while (n != 0);
srcp = src;
do {
/* Look to see if we can use pointers. */
n = *srcp;
if (n != 0 && msg != NULL) {
l = dn_find(srcp, msg, (const u_char * const *)dnptrs,
(const u_char * const *)lpp);
if (l >= 0) {
if (dstp + 1 >= eob) {
errno = EMSGSIZE;
return (-1);
}
*dstp++ = (l >> 8) | NS_CMPRSFLGS;
*dstp++ = l % 256;
return (dstp - dst);
}
/* Not found, save it. */
if (lastdnptr != NULL && cpp < lastdnptr - 1 &&
(dstp - msg) < 0x4000) {
*cpp++ = dstp;
*cpp = NULL;
}
}
/* copy label to buffer */
if (n & NS_CMPRSFLGS) { /* Should not happen. */
errno = EMSGSIZE;
return (-1);
}
if (dstp + 1 + n >= eob) {
errno = EMSGSIZE;
return (-1);
}
memcpy(dstp, srcp, n + 1);
srcp += n + 1;
dstp += n + 1;
} while (n != 0);
if (dstp > eob) {
if (msg != NULL)
*lpp = NULL;
errno = EMSGSIZE;
return (-1);
}
return (dstp - dst);
}
/*
* ns_name_uncompress(msg, eom, src, dst, dstsiz)
* Expand compressed domain name to presentation format.
* return:
* Number of bytes read out of `src', or -1 (with errno set).
* note:
* Root domain returns as "." not "".
*/
static int
ns_name_uncompress(msg, eom, src, dst, dstsiz)
const u_char *msg;
const u_char *eom;
const u_char *src;
char *dst;
size_t dstsiz;
{
u_char tmp[NS_MAXCDNAME];
int n;
if ((n = ns_name_unpack(msg, eom, src, tmp, sizeof tmp)) == -1)
return (-1);
if (ns_name_ntop(tmp, dst, dstsiz) == -1)
return (-1);
return (n);
}
/*
* ns_name_compress(src, dst, dstsiz, dnptrs, lastdnptr)
* Compress a domain name into wire format, using compression pointers.
* return:
* Number of bytes consumed in `dst' or -1 (with errno set).
* notes:
* 'dnptrs' is an array of pointers to previous compressed names.
* dnptrs[0] is a pointer to the beginning of the message.
* The list ends with NULL. 'lastdnptr' is a pointer to the end of the
* array pointed to by 'dnptrs'. Side effect is to update the list of
* pointers for labels inserted into the message as we compress the name.
* If 'dnptr' is NULL, we don't try to compress names. If 'lastdnptr'
* is NULL, we don't update the list.
*/
static int
ns_name_compress(src, dst, dstsiz, dnptrs, lastdnptr)
const char *src;
u_char *dst;
size_t dstsiz;
const u_char **dnptrs;
const u_char **lastdnptr;
{
u_char tmp[NS_MAXCDNAME];
if (ns_name_pton(src, tmp, sizeof tmp) == -1)
return (-1);
return (ns_name_pack(tmp, dst, dstsiz, dnptrs, lastdnptr));
}
/*
* ns_name_skip(ptrptr, eom)
* Advance *ptrptr to skip over the compressed name it points at.
* return:
* 0 on success, -1 (with errno set) on failure.
*/
static int
ns_name_skip(ptrptr, eom)
const u_char **ptrptr;
const u_char *eom;
{
const u_char *cp;
u_int n;
cp = *ptrptr;
while (cp < eom && (n = *cp++) != 0) {
/* Check for indirection. */
switch (n & NS_CMPRSFLGS) {
case 0: /* normal case, n == len */
cp += n;
continue;
case NS_CMPRSFLGS: /* indirection */
cp++;
break;
default: /* illegal type */
errno = EMSGSIZE;
return (-1);
}
break;
}
if (cp > eom) {
errno = EMSGSIZE;
return (-1);
}
*ptrptr = cp;
return (0);
}
/* Private. */
/*
* special(ch)
* Thinking in noninternationalized USASCII (per the DNS spec),
* is this characted special ("in need of quoting") ?
* return:
* boolean.
*/
static int
special(ch)
int ch;
{
switch (ch) {
case 0x22: /* '"' */
case 0x2E: /* '.' */
case 0x3B: /* ';' */
case 0x5C: /* '\\' */
/* Special modifiers in zone files. */
case 0x40: /* '@' */
case 0x24: /* '$' */
return (1);
default:
return (0);
}
}
/*
* printable(ch)
* Thinking in noninternationalized USASCII (per the DNS spec),
* is this character visible and not a space when printed ?
* return:
* boolean.
*/
static int
printable(ch)
int ch;
{
return (ch > 0x20 && ch < 0x7f);
}
/*
* Thinking in noninternationalized USASCII (per the DNS spec),
* convert this character to lower case if it's upper case.
*/
static int
mklower(ch)
int ch;
{
if (ch >= 0x41 && ch <= 0x5A)
return (ch + 0x20);
return (ch);
}
/*
* dn_find(domain, msg, dnptrs, lastdnptr)
* Search for the counted-label name in an array of compressed names.
* return:
* offset from msg if found, or -1.
* notes:
* dnptrs is the pointer to the first name on the list,
* not the pointer to the start of the message.
*/
static int
dn_find(domain, msg, dnptrs, lastdnptr)
const u_char *domain;
const u_char *msg;
const u_char * const *dnptrs;
const u_char * const *lastdnptr;
{
const u_char *dn, *cp, *sp;
const u_char * const *cpp;
u_int n;
for (cpp = dnptrs; cpp < lastdnptr; cpp++) {
dn = domain;
sp = cp = *cpp;
while ((n = *cp++) != 0) {
/*
* check for indirection
*/
switch (n & NS_CMPRSFLGS) {
case 0: /* normal case, n == len */
if (n != *dn++)
goto next;
for ((void)NULL; n > 0; n--)
if (mklower(*dn++) != mklower(*cp++))
goto next;
/* Is next root for both ? */
if (*dn == '\0' && *cp == '\0')
return (sp - msg);
if (*dn)
continue;
goto next;
case NS_CMPRSFLGS: /* indirection */
cp = msg + (((n & 0x3f) << 8) | *cp);
break;
default: /* illegal type */
errno = EMSGSIZE;
return (-1);
}
}
next: ;
}
errno = ENOENT;
return (-1);
}
/* -- From BIND 8.1.1. -- */

View File

@ -1,8 +1,8 @@
#define DEBUG 1 /* enable debugging code (needed for dig) */ #define DEBUG 1 /* enable debugging code (needed for dig) */
#undef ALLOW_T_UNSPEC /* enable the "unspec" RR type for old athena */
#define RESOLVSORT /* allow sorting of addresses in gethostbyname */ #define RESOLVSORT /* allow sorting of addresses in gethostbyname */
#define RFC1535 /* comply with RFC1535 (STRONGLY reccomended by vixie)*/ #define RFC1535 /* comply with RFC1535 (STRONGLY reccomended by vixie)*/
#undef USELOOPBACK /* res_init() bind to localhost */ #undef USELOOPBACK /* res_init() bind to localhost */
#undef SUNSECURITY /* verify gethostbyaddr() calls - WE DONT NEED IT */ #undef SUNSECURITY /* verify gethostbyaddr() calls - WE DONT NEED IT */
#define MULTI_PTRS_ARE_ALIASES 1 /* fold multiple PTR records into aliases */ #define MULTI_PTRS_ARE_ALIASES 1 /* fold multiple PTR records into aliases */
#define CHECK_SRVR_ADDR 1 /* confirm that the server requested sent the reply */ #define CHECK_SRVR_ADDR 1 /* confirm that the server requested sent the reply */
#define BIND_UPDATE 1 /* update support */

View File

@ -1,60 +1,22 @@
/* /*
* ++Copyright++ 1995 * Copyright (c) 1995,1996 by Internet Software Consortium.
* - *
* Copyright (c) 1995
* The Regents of the University of California. 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. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
* -
* Portions Copyright (c) 1993 by Digital Equipment Corporation.
*
* Permission to use, copy, modify, and distribute this software for any * Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above * purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies, and that * copyright notice and this permission notice appear in all copies.
* the name of Digital Equipment Corporation not be used in advertising or *
* publicity pertaining to distribution of the document or software without * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
* specific, written prior permission. * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
* * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
* THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
* WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT
* CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS * 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 * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
* SOFTWARE. * SOFTWARE.
* -
* --Copyright--
*/ */
#if defined(LIBC_SCCS) && !defined(lint) #if defined(LIBC_SCCS) && !defined(lint)
static char rcsid[] = "$Id$"; static char rcsid[] = "$Id: res_data.c,v 1.5 1997/02/22 15:00:30 peter Exp $";
#endif /* LIBC_SCCS and not lint */ #endif /* LIBC_SCCS and not lint */
#include <sys/types.h> #include <sys/types.h>
@ -64,13 +26,14 @@ static char rcsid[] = "$Id$";
#include <netinet/in.h> #include <netinet/in.h>
#include <arpa/inet.h> #include <arpa/inet.h>
#include <arpa/nameser.h> #include <arpa/nameser.h>
#include <stdio.h>
#include <ctype.h> #include <ctype.h>
#include <resolv.h> #include <resolv.h>
#include <unistd.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <unistd.h>
#include "res_config.h"
const char *_res_opcodes[] = { const char *_res_opcodes[] = {
"QUERY", "QUERY",
@ -78,15 +41,15 @@ const char *_res_opcodes[] = {
"CQUERYM", "CQUERYM",
"CQUERYU", /* experimental */ "CQUERYU", /* experimental */
"NOTIFY", /* experimental */ "NOTIFY", /* experimental */
"5", "UPDATE",
"6", "6",
"7", "7",
"8", "8",
"UPDATEA", "9",
"UPDATED", "10",
"UPDATEDA", "11",
"UPDATEM", "12",
"UPDATEMA", "13",
"ZONEINIT", "ZONEINIT",
"ZONEREF", "ZONEREF",
}; };
@ -98,14 +61,23 @@ const char *_res_resultcodes[] = {
"NXDOMAIN", "NXDOMAIN",
"NOTIMP", "NOTIMP",
"REFUSED", "REFUSED",
"6", "YXDOMAIN",
"7", "YXRRSET",
"8", "NXRRSET",
"9", "NOTAUTH",
"10", "ZONEERR",
"11", "11",
"12", "12",
"13", "13",
"14", "14",
"NOCHANGE", "NOCHANGE",
}; };
#ifdef BIND_UPDATE
const char *_res_sectioncodes[] = {
"ZONE",
"PREREQUISITES",
"UPDATE",
"ADDITIONAL",
};
#endif

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,4 @@
/* /*
* ++Copyright++ 1985, 1989, 1993
* -
* Copyright (c) 1985, 1989, 1993 * Copyright (c) 1985, 1989, 1993
* The Regents of the University of California. All rights reserved. * The Regents of the University of California. All rights reserved.
* *
@ -31,7 +29,9 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * 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 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE. * SUCH DAMAGE.
* - */
/*
* Portions Copyright (c) 1993 by Digital Equipment Corporation. * Portions Copyright (c) 1993 by Digital Equipment Corporation.
* *
* Permission to use, copy, modify, and distribute this software for any * Permission to use, copy, modify, and distribute this software for any
@ -49,14 +49,29 @@
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS * 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 * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
* SOFTWARE. * SOFTWARE.
* - */
* --Copyright--
/*
* Portions Copyright (c) 1996 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) #if defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "@(#)res_init.c 8.1 (Berkeley) 6/7/93"; static char sccsid[] = "@(#)res_init.c 8.1 (Berkeley) 6/7/93";
static char orig_rcsid[] = "From: Id: res_init.c,v 8.8 1997/06/01 20:34:37 vixie Exp"; static char orig_rcsid[] = "From: Id: res_init.c,v 8.7 1996/11/18 09:10:04 vixie Exp $";
static char rcsid[] = "$Id: res_init.c,v 1.13 1997/06/27 08:22:03 peter Exp $"; static char rcsid[] = "$Id: res_init.c,v 1.14 1997/09/01 01:19:20 brian Exp $";
#endif /* LIBC_SCCS and not lint */ #endif /* LIBC_SCCS and not lint */
#include <sys/types.h> #include <sys/types.h>
@ -65,16 +80,15 @@ static char rcsid[] = "$Id: res_init.c,v 1.13 1997/06/27 08:22:03 peter Exp $";
#include <sys/time.h> #include <sys/time.h>
#include <netinet/in.h> #include <netinet/in.h>
#include <arpa/inet.h> #include <arpa/inet.h>
#include "res_config.h"
#include <arpa/nameser.h> #include <arpa/nameser.h>
#include <stdio.h>
#include <ctype.h> #include <ctype.h>
#include <resolv.h> #include <resolv.h>
#include <unistd.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <unistd.h>
#include "res_config.h"
static void res_setoptions __P((char *, char *)); static void res_setoptions __P((char *, char *));
@ -84,6 +98,10 @@ static const char sort_mask[] = "/&";
static u_int32_t net_mask __P((struct in_addr)); static u_int32_t net_mask __P((struct in_addr));
#endif #endif
#if !defined(isascii) /* XXX - could be a function */
# define isascii(c) (!(c & 0200))
#endif
/* /*
* Resolver state default settings. * Resolver state default settings.
*/ */
@ -94,6 +112,7 @@ struct __res_state _res
# endif # endif
; ;
/* /*
* Set up default settings. If the configuration file exist, the values * Set up default settings. If the configuration file exist, the values
* there will have precedence. Otherwise, the server address is set to * there will have precedence. Otherwise, the server address is set to
@ -376,7 +395,7 @@ res_init()
printf(";;\t%s\n", *pp); printf(";;\t%s\n", *pp);
printf(";;\t..END..\n"); printf(";;\t..END..\n");
} }
#endif /* DEBUG */ #endif
#endif /* !RFC1535 */ #endif /* !RFC1535 */
} }

View File

@ -1,6 +1,4 @@
/* /*
* ++Copyright++ 1985, 1993
* -
* Copyright (c) 1985, 1993 * Copyright (c) 1985, 1993
* The Regents of the University of California. All rights reserved. * The Regents of the University of California. All rights reserved.
* *
@ -31,7 +29,9 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * 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 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE. * SUCH DAMAGE.
* - */
/*
* Portions Copyright (c) 1993 by Digital Equipment Corporation. * Portions Copyright (c) 1993 by Digital Equipment Corporation.
* *
* Permission to use, copy, modify, and distribute this software for any * Permission to use, copy, modify, and distribute this software for any
@ -49,28 +49,41 @@
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS * 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 * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
* SOFTWARE. * SOFTWARE.
* - */
* --Copyright--
/*
* Portions Copyright (c) 1996 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) #if defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "@(#)res_mkquery.c 8.1 (Berkeley) 6/4/93"; static char sccsid[] = "@(#)res_mkquery.c 8.1 (Berkeley) 6/4/93";
static char orig_rcsid[] = "From: Id: res_mkquery.c,v 8.5 1996/08/27 08:33:28 vixie Exp "; static char orig_rcsid[] = "From: Id: res_mkquery.c,v 8.9 1997/04/24 22:22:36 vixie Exp $";
static char rcsid[] = "$Id$"; static char rcsid[] = "$Id: res_mkquery.c,v 1.12 1997/02/22 15:00:33 peter Exp $";
#endif /* LIBC_SCCS and not lint */ #endif /* LIBC_SCCS and not lint */
#include <sys/types.h> #include <sys/types.h>
#include <sys/param.h> #include <sys/param.h>
#include <netinet/in.h> #include <netinet/in.h>
#include "res_config.h"
#include <arpa/nameser.h> #include <arpa/nameser.h>
#include <stdio.h>
#include <netdb.h> #include <netdb.h>
#include <resolv.h> #include <resolv.h>
#include <stdio.h>
#include <string.h> #include <string.h>
#include "res_config.h"
/* /*
* Form all types of queries. * Form all types of queries.
@ -106,7 +119,7 @@ res_mkquery(op, dname, class, type, data, datalen, newrr_in, buf, buflen)
*/ */
if ((buf == NULL) || (buflen < HFIXEDSZ)) if ((buf == NULL) || (buflen < HFIXEDSZ))
return (-1); return (-1);
bzero(buf, HFIXEDSZ); memset(buf, 0, HFIXEDSZ);
hp = (HEADER *) buf; hp = (HEADER *) buf;
hp->id = htons(++_res.id); hp->id = htons(++_res.id);
hp->opcode = op; hp->opcode = op;
@ -173,7 +186,7 @@ res_mkquery(op, dname, class, type, data, datalen, newrr_in, buf, buflen)
__putshort(datalen, cp); __putshort(datalen, cp);
cp += INT16SZ; cp += INT16SZ;
if (datalen) { if (datalen) {
bcopy(data, cp, datalen); memcpy(cp, data, datalen);
cp += datalen; cp += datalen;
} }
hp->ancount = htons(1); hp->ancount = htons(1);

414
lib/libc/net/res_mkupdate.c Normal file
View File

@ -0,0 +1,414 @@
/*
* Copyright (c) 1996 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.
*/
/*
* Based on the Dynamic DNS reference implementation by Viraj Bais
* <viraj_bais@ccm.fm.intel.com>
*/
#if !defined(lint) && !defined(SABER)
static char rcsid[] = "$Id: res_mkupdate.c,v 1.11 1998/01/26 23:08:45 halley Exp $";
#endif /* not lint */
#include <sys/types.h>
#include <sys/param.h>
#include <netinet/in.h>
#include <arpa/nameser.h>
#include <arpa/inet.h>
#include <errno.h>
#include <limits.h>
#include <netdb.h>
#include <resolv.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <ctype.h>
#include "res_config.h"
static int getnum_str(u_char **, u_char *);
static int getword_str(char *, int, u_char **, u_char *);
#define ShrinkBuffer(x) if ((buflen -= x) < 0) return (-2);
/*
* Form update packets.
* Returns the size of the resulting packet if no error
* On error,
* returns -1 if error in reading a word/number in rdata
* portion for update packets
* -2 if length of buffer passed is insufficient
* -3 if zone section is not the first section in
* the linked list, or section order has a problem
* -4 on a number overflow
* -5 unknown operation or no records
*/
int
res_mkupdate(ns_updrec *rrecp_in, u_char *buf, int buflen) {
ns_updrec *rrecp_start = rrecp_in;
HEADER *hp;
u_char c, *cp, *cp1, *sp1, *sp2, *startp, *endp;
int n, i, j, found, soanum, multiline;
ns_updrec *rrecp, *tmprrecp, *recptr = NULL;
struct in_addr ina;
char buf2[MAXDNAME];
int section, numrrs = 0, counts[ns_s_max];
u_int16_t rtype, rclass;
u_int32_t n1, rttl;
u_char *dnptrs[20], **dpp, **lastdnptr;
if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
h_errno = NETDB_INTERNAL;
return (-1);
}
/*
* Initialize header fields.
*/
if ((buf == NULL) || (buflen < HFIXEDSZ))
return (-1);
memset(buf, 0, HFIXEDSZ);
hp = (HEADER *) buf;
hp->id = htons(++_res.id);
hp->opcode = ns_o_update;
hp->rcode = NOERROR;
sp1 = buf + 2*INT16SZ; /* save pointer to zocount */
cp = buf + HFIXEDSZ;
buflen -= HFIXEDSZ;
dpp = dnptrs;
*dpp++ = buf;
*dpp++ = NULL;
lastdnptr = dnptrs + sizeof dnptrs / sizeof dnptrs[0];
if (rrecp_start == NULL)
return (-5);
else if (rrecp_start->r_section != S_ZONE)
return (-3);
memset(counts, 0, sizeof counts);
for (rrecp = rrecp_start; rrecp; rrecp = rrecp->r_grpnext) {
numrrs++;
section = rrecp->r_section;
if (section < 0 || section >= ns_s_max)
return (-1);
counts[section]++;
for (i = section + 1; i < ns_s_max; i++)
if (counts[i])
return (-3);
rtype = rrecp->r_type;
rclass = rrecp->r_class;
rttl = rrecp->r_ttl;
/* overload class and type */
if (section == S_PREREQ) {
rttl = 0;
switch (rrecp->r_opcode) {
case YXDOMAIN:
rclass = C_ANY;
rtype = T_ANY;
rrecp->r_size = 0;
break;
case NXDOMAIN:
rclass = C_NONE;
rtype = T_ANY;
rrecp->r_size = 0;
break;
case NXRRSET:
rclass = C_NONE;
rrecp->r_size = 0;
break;
case YXRRSET:
if (rrecp->r_size == 0)
rclass = C_ANY;
break;
default:
fprintf(stderr,
"res_mkupdate: incorrect opcode: %d\n",
rrecp->r_opcode);
fflush(stderr);
return (-1);
}
} else if (section == S_UPDATE) {
switch (rrecp->r_opcode) {
case DELETE:
rclass = rrecp->r_size == 0 ? C_ANY : C_NONE;
break;
case ADD:
break;
default:
fprintf(stderr,
"res_mkupdate: incorrect opcode: %d\n",
rrecp->r_opcode);
fflush(stderr);
return (-1);
}
}
/*
* XXX appending default domain to owner name is omitted,
* fqdn must be provided
*/
if ((n = dn_comp(rrecp->r_dname, cp, buflen, dnptrs,
lastdnptr)) < 0)
return (-1);
cp += n;
ShrinkBuffer(n + 2*INT16SZ);
PUTSHORT(rtype, cp);
PUTSHORT(rclass, cp);
if (section == S_ZONE) {
if (numrrs != 1 || rrecp->r_type != T_SOA)
return (-3);
continue;
}
ShrinkBuffer(INT32SZ + INT16SZ);
PUTLONG(rttl, cp);
sp2 = cp; /* save pointer to length byte */
cp += INT16SZ;
if (rrecp->r_size == 0) {
if (section == S_UPDATE && rclass != C_ANY)
return (-1);
else {
PUTSHORT(0, sp2);
continue;
}
}
startp = rrecp->r_data;
endp = startp + rrecp->r_size - 1;
/* XXX this should be done centrally. */
switch (rrecp->r_type) {
case T_A:
if (!getword_str(buf2, sizeof buf2, &startp, endp))
return (-1);
if (!inet_aton(buf2, &ina))
return (-1);
n1 = ntohl(ina.s_addr);
ShrinkBuffer(INT32SZ);
PUTLONG(n1, cp);
break;
case T_CNAME:
case T_MB:
case T_MG:
case T_MR:
case T_NS:
case T_PTR:
if (!getword_str(buf2, sizeof buf2, &startp, endp))
return (-1);
n = dn_comp(buf2, cp, buflen, dnptrs, lastdnptr);
if (n < 0)
return (-1);
cp += n;
ShrinkBuffer(n);
break;
case T_MINFO:
case T_SOA:
case T_RP:
for (i = 0; i < 2; i++) {
if (!getword_str(buf2, sizeof buf2, &startp,
endp))
return (-1);
n = dn_comp(buf2, cp, buflen,
dnptrs, lastdnptr);
if (n < 0)
return (-1);
cp += n;
ShrinkBuffer(n);
}
if (rrecp->r_type == T_SOA) {
ShrinkBuffer(5 * INT32SZ);
while (isspace(*startp) || !*startp)
startp++;
if (*startp == '(') {
multiline = 1;
startp++;
} else
multiline = 0;
/* serial, refresh, retry, expire, minimum */
for (i = 0; i < 5; i++) {
soanum = getnum_str(&startp, endp);
if (soanum < 0)
return (-1);
PUTLONG(soanum, cp);
}
if (multiline) {
while (isspace(*startp) || !*startp)
startp++;
if (*startp != ')')
return (-1);
}
}
break;
case T_MX:
case T_AFSDB:
case T_RT:
n = getnum_str(&startp, endp);
if (n < 0)
return (-1);
PUTSHORT(n, cp);
ShrinkBuffer(INT16SZ);
if (!getword_str(buf2, sizeof buf2, &startp, endp))
return (-1);
n = dn_comp(buf2, cp, buflen, dnptrs, lastdnptr);
if (n < 0)
return (-1);
cp += n;
ShrinkBuffer(n);
break;
case T_PX:
n = getnum_str(&startp, endp);
if (n < 0)
return (-1);
PUTSHORT(n, cp);
ShrinkBuffer(INT16SZ);
for (i = 0; i < 2; i++) {
if (!getword_str(buf2, sizeof buf2, &startp,
endp))
return (-1);
n = dn_comp(buf2, cp, buflen, dnptrs,
lastdnptr);
if (n < 0)
return (-1);
cp += n;
ShrinkBuffer(n);
}
break;
case T_WKS:
case T_HINFO:
case T_TXT:
case T_X25:
case T_ISDN:
case T_NSAP:
case T_LOC:
/* XXX - more fine tuning needed here */
ShrinkBuffer(rrecp->r_size);
memcpy(cp, rrecp->r_data, rrecp->r_size);
cp += rrecp->r_size;
break;
default:
return (-1);
} /*switch*/
n = (u_int16_t)((cp - sp2) - INT16SZ);
PUTSHORT(n, sp2);
} /*for*/
hp->qdcount = htons(counts[0]);
hp->ancount = htons(counts[1]);
hp->nscount = htons(counts[2]);
hp->arcount = htons(counts[3]);
return (cp - buf);
}
/*
* Get a whitespace delimited word from a string (not file)
* into buf. modify the start pointer to point after the
* word in the string.
*/
static int
getword_str(char *buf, int size, u_char **startpp, u_char *endp) {
char *cp;
int c;
for (cp = buf; *startpp <= endp; ) {
c = **startpp;
if (isspace(c) || c == '\0') {
if (cp != buf) /* trailing whitespace */
break;
else { /* leading whitespace */
(*startpp)++;
continue;
}
}
(*startpp)++;
if (cp >= buf+size-1)
break;
*cp++ = (u_char)c;
}
*cp = '\0';
return (cp != buf);
}
/*
* Get a whitespace delimited number from a string (not file) into buf
* update the start pointer to point after the number in the string.
*/
static int
getnum_str(u_char **startpp, u_char *endp) {
int c, n;
int seendigit = 0;
int seendecimal = 0;
int m = 0;
for (n = 0; *startpp <= endp; ) {
c = **startpp;
if (isspace(c) || c == '\0') {
if (seendigit) /* trailing whitespace */
break;
else { /* leading whitespace */
(*startpp)++;
continue;
}
}
if (c == ';') {
while ((*startpp <= endp) &&
((c = **startpp) != '\n'))
(*startpp)++;
if (seendigit)
break;
continue;
}
if (!isdigit(c)) {
if (c == ')' && seendigit) {
(*startpp)--;
break;
}
return (-1);
}
(*startpp)++;
n = n * 10 + (c - '0');
seendigit = 1;
}
return (n + m);
}
/*
* Allocate a resource record buffer & save rr info.
*/
ns_updrec *
res_mkupdrec(int section, const char *dname,
u_int class, u_int type, u_long ttl) {
ns_updrec *rrecp = (ns_updrec *)calloc(1, sizeof(ns_updrec));
if (!rrecp || !(rrecp->r_dname = strdup(dname)))
return (NULL);
rrecp->r_class = class;
rrecp->r_type = type;
rrecp->r_ttl = ttl;
rrecp->r_section = section;
return (rrecp);
}
/*
* Free a resource record buffer created by res_mkupdrec.
*/
void
res_freeupdrec(ns_updrec *rrecp) {
/* Note: freeing r_dp is the caller's responsibility. */
if (rrecp->r_dname != NULL)
free(rrecp->r_dname);
free(rrecp);
}

View File

@ -1,6 +1,4 @@
/* /*
* ++Copyright++ 1988, 1993
* -
* Copyright (c) 1988, 1993 * Copyright (c) 1988, 1993
* The Regents of the University of California. All rights reserved. * The Regents of the University of California. All rights reserved.
* *
@ -31,7 +29,9 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * 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 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE. * SUCH DAMAGE.
* - */
/*
* Portions Copyright (c) 1993 by Digital Equipment Corporation. * Portions Copyright (c) 1993 by Digital Equipment Corporation.
* *
* Permission to use, copy, modify, and distribute this software for any * Permission to use, copy, modify, and distribute this software for any
@ -49,41 +49,52 @@
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS * 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 * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
* SOFTWARE. * SOFTWARE.
* - */
* --Copyright--
/*
* Portions Copyright (c) 1996 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) #if defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "@(#)res_query.c 8.1 (Berkeley) 6/4/93"; static char sccsid[] = "@(#)res_query.c 8.1 (Berkeley) 6/4/93";
static char orig_rcsid = "From: Id: res_query.c,v 8.10 1997/06/01 20:34:37 vixie Exp"; static char orig_rcsid = "From: Id: res_query.c,v 8.14 1997/06/09 17:47:05 halley Exp $";
static char rcsid[] = "$Id: res_query.c,v 1.14 1997/06/27 08:22:03 peter Exp $"; static char rcsid[] = "$Id: res_query.c,v 1.15 1997/09/01 01:19:21 brian Exp $";
#endif /* LIBC_SCCS and not lint */ #endif /* LIBC_SCCS and not lint */
#include <sys/types.h> #include <sys/types.h>
#include <sys/param.h> #include <sys/param.h>
#include <netinet/in.h> #include <netinet/in.h>
#include <arpa/inet.h> #include <arpa/inet.h>
#include "res_config.h"
#include <arpa/nameser.h> #include <arpa/nameser.h>
#include <stdio.h>
#include <netdb.h>
#include <resolv.h>
#include <ctype.h> #include <ctype.h>
#include <errno.h> #include <errno.h>
#include <netdb.h>
#include <resolv.h>
#include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include "res_config.h"
#if PACKETSZ > 1024 #if PACKETSZ > 1024
#define MAXPACKET PACKETSZ #define MAXPACKET PACKETSZ
#else #else
#define MAXPACKET 1024 #define MAXPACKET 1024
#endif #endif
const char *hostalias __P((const char *));
int h_errno;
/* /*
* Formulate a normal query, send, and await answer. * Formulate a normal query, send, and await answer.
* Returned answer is placed in supplied buffer "answer". * Returned answer is placed in supplied buffer "answer".
@ -102,7 +113,7 @@ res_query(name, class, type, answer, anslen)
int anslen; /* size of answer buffer */ int anslen; /* size of answer buffer */
{ {
u_char buf[MAXPACKET]; u_char buf[MAXPACKET];
register HEADER *hp = (HEADER *) answer; HEADER *hp = (HEADER *) answer;
int n; int n;
hp->rcode = NOERROR; /* default */ hp->rcode = NOERROR; /* default */
@ -177,7 +188,7 @@ res_search(name, class, type, answer, anslen)
u_char *answer; /* buffer to put answer */ u_char *answer; /* buffer to put answer */
int anslen; /* size of answer */ int anslen; /* size of answer */
{ {
register const char *cp, * const *domain; const char *cp, * const *domain;
HEADER *hp = (HEADER *) answer; HEADER *hp = (HEADER *) answer;
u_int dots; u_int dots;
int trailing_dot, ret, saved_herrno; int trailing_dot, ret, saved_herrno;
@ -196,10 +207,8 @@ res_search(name, class, type, answer, anslen)
if (cp > name && *--cp == '.') if (cp > name && *--cp == '.')
trailing_dot++; trailing_dot++;
/* /* If there aren't any dots, it could be a user-level alias */
* if there aren't any dots, it could be a user-level alias if (!dots && (cp = hostalias(name)) != NULL)
*/
if (!dots && (cp = __hostalias(name)) != NULL)
return (res_query(cp, class, type, answer, anslen)); return (res_query(cp, class, type, answer, anslen));
/* /*
@ -279,7 +288,8 @@ res_search(name, class, type, answer, anslen)
} }
} }
/* if we have not already tried the name "as is", do that now. /*
* If we have not already tried the name "as is", do that now.
* note that we do this regardless of how many dots were in the * note that we do this regardless of how many dots were in the
* name or whether it ends with a dot unless NOTLDQUERY is set. * name or whether it ends with a dot unless NOTLDQUERY is set.
*/ */
@ -359,7 +369,7 @@ res_querydomain(name, domain, class, type, answer, anslen)
const char * const char *
hostalias(name) hostalias(name)
register const char *name; const char *name;
{ {
register char *cp1, *cp2; register char *cp1, *cp2;
FILE *fp; FILE *fp;
@ -369,8 +379,7 @@ hostalias(name)
if (_res.options & RES_NOALIASES) if (_res.options & RES_NOALIASES)
return (NULL); return (NULL);
/* XXX issetguid() would be better here, but we don't have that. */ if (issetugid())
if (getuid() != geteuid() || getgid() != getegid())
return (NULL); return (NULL);
file = getenv("HOSTALIASES"); file = getenv("HOSTALIASES");
if (file == NULL || (fp = fopen(file, "r")) == NULL) if (file == NULL || (fp = fopen(file, "r")) == NULL)

View File

@ -1,6 +1,4 @@
/* /*
* ++Copyright++ 1985, 1989, 1993
* -
* Copyright (c) 1985, 1989, 1993 * Copyright (c) 1985, 1989, 1993
* The Regents of the University of California. All rights reserved. * The Regents of the University of California. All rights reserved.
* *
@ -31,7 +29,9 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * 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 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE. * SUCH DAMAGE.
* - */
/*
* Portions Copyright (c) 1993 by Digital Equipment Corporation. * Portions Copyright (c) 1993 by Digital Equipment Corporation.
* *
* Permission to use, copy, modify, and distribute this software for any * Permission to use, copy, modify, and distribute this software for any
@ -49,14 +49,29 @@
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS * 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 * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
* SOFTWARE. * SOFTWARE.
* - */
* --Copyright--
/*
* Portions Copyright (c) 1996 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) #if defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "@(#)res_send.c 8.1 (Berkeley) 6/4/93"; static char sccsid[] = "@(#)res_send.c 8.1 (Berkeley) 6/4/93";
static char orig_rcsid[] = "From: Id: res_send.c,v 8.14 1998/04/07 04:59:46 vixie Exp $"; static char orig_rcsid[] = "From: Id: res_send.c,v 8.20 1998/04/06 23:27:51 halley Exp $";
static char rcsid[] = "$Id: res_send.c,v 1.21 1998/05/02 13:11:02 peter Exp $"; static char rcsid[] = "$Id: res_send.c,v 1.22 1998/05/02 15:51:54 peter Exp $";
#endif /* LIBC_SCCS and not lint */ #endif /* LIBC_SCCS and not lint */
/* /*
@ -68,27 +83,31 @@ static char rcsid[] = "$Id: res_send.c,v 1.21 1998/05/02 13:11:02 peter Exp $";
#include <sys/time.h> #include <sys/time.h>
#include <sys/socket.h> #include <sys/socket.h>
#include <sys/uio.h> #include <sys/uio.h>
#include <netinet/in.h> #include <netinet/in.h>
#include <arpa/nameser.h>
#include <arpa/inet.h> #include <arpa/inet.h>
#include "res_config.h"
#include <arpa/nameser.h>
#include <stdio.h>
#include <netdb.h>
#include <errno.h> #include <errno.h>
#include <netdb.h>
#include <resolv.h> #include <resolv.h>
#include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <unistd.h> #include <unistd.h>
#include <poll.h> #include <poll.h>
#include "res_config.h"
static int use_poll = 1; /* adapt to poll() syscall availability */ static int use_poll = 1; /* adapt to poll() syscall availability */
/* 0 = not present, 1 = try it, 2 = exists */ /* 0 = not present, 1 = try it, 2 = exists */
static int s = -1; /* socket used for communications */ static int s = -1; /* socket used for communications */
static int connected = 0; /* is the socket connected */ static int connected = 0; /* is the socket connected */
static int vc = 0; /* is the socket a virtual ciruit? */ static int vc = 0; /* is the socket a virtual circuit? */
static res_send_qhook Qhook = NULL;
static res_send_rhook Rhook = NULL;
#define CAN_RECONNECT 1 #define CAN_RECONNECT 1
@ -137,9 +156,6 @@ static int vc = 0; /* is the socket a virtual ciruit? */
} }
#endif #endif
static res_send_qhook Qhook = NULL;
static res_send_rhook Rhook = NULL;
void void
res_send_setqhook(hook) res_send_setqhook(hook)
res_send_qhook hook; res_send_qhook hook;
@ -170,12 +186,12 @@ res_isourserver(inp)
const struct sockaddr_in *inp; const struct sockaddr_in *inp;
{ {
struct sockaddr_in ina; struct sockaddr_in ina;
register int ns, ret; int ns, ret;
ina = *inp; ina = *inp;
ret = 0; ret = 0;
for (ns = 0; ns < _res.nscount; ns++) { for (ns = 0; ns < _res.nscount; ns++) {
register const struct sockaddr_in *srv = &_res.nsaddr_list[ns]; const struct sockaddr_in *srv = &_res.nsaddr_list[ns];
if (srv->sin_family == ina.sin_family && if (srv->sin_family == ina.sin_family &&
srv->sin_port == ina.sin_port && srv->sin_port == ina.sin_port &&
@ -192,7 +208,7 @@ res_isourserver(inp)
* res_nameinquery(name, type, class, buf, eom) * res_nameinquery(name, type, class, buf, eom)
* look for (name,type,class) in the query section of packet (buf,eom) * look for (name,type,class) in the query section of packet (buf,eom)
* requires: * requires:
* buf + HFIXESDZ <= eom * buf + HFIXEDSZ <= eom
* returns: * returns:
* -1 : format error * -1 : format error
* 0 : not found * 0 : not found
@ -203,15 +219,15 @@ res_isourserver(inp)
int int
res_nameinquery(name, type, class, buf, eom) res_nameinquery(name, type, class, buf, eom)
const char *name; const char *name;
register int type, class; int type, class;
const u_char *buf, *eom; const u_char *buf, *eom;
{ {
register const u_char *cp = buf + HFIXEDSZ; const u_char *cp = buf + HFIXEDSZ;
int qdcount = ntohs(((HEADER*)buf)->qdcount); int qdcount = ntohs(((HEADER*)buf)->qdcount);
while (qdcount-- > 0) { while (qdcount-- > 0) {
char tname[MAXDNAME+1]; char tname[MAXDNAME+1];
register int n, ttype, tclass; int n, ttype, tclass;
n = dn_expand(buf, eom, cp, tname, sizeof tname); n = dn_expand(buf, eom, cp, tname, sizeof tname);
if (n < 0) if (n < 0)
@ -219,8 +235,8 @@ res_nameinquery(name, type, class, buf, eom)
cp += n; cp += n;
if (cp + 2 * INT16SZ > eom) if (cp + 2 * INT16SZ > eom)
return (-1); return (-1);
ttype = _getshort(cp); cp += INT16SZ; ttype = ns_get16(cp); cp += INT16SZ;
tclass = _getshort(cp); cp += INT16SZ; tclass = ns_get16(cp); cp += INT16SZ;
if (ttype == type && if (ttype == type &&
tclass == class && tclass == class &&
strcasecmp(tname, name) == 0) strcasecmp(tname, name) == 0)
@ -245,17 +261,25 @@ res_queriesmatch(buf1, eom1, buf2, eom2)
const u_char *buf1, *eom1; const u_char *buf1, *eom1;
const u_char *buf2, *eom2; const u_char *buf2, *eom2;
{ {
register const u_char *cp = buf1 + HFIXEDSZ; const u_char *cp = buf1 + HFIXEDSZ;
int qdcount = ntohs(((HEADER*)buf1)->qdcount); int qdcount = ntohs(((HEADER*)buf1)->qdcount);
if (buf1 + HFIXEDSZ > eom1 || buf2 + HFIXEDSZ > eom2) if (buf1 + HFIXEDSZ > eom1 || buf2 + HFIXEDSZ > eom2)
return (-1); return (-1);
/*
* Only header section present in replies to
* dynamic update packets.
*/
if ( (((HEADER *)buf1)->opcode == ns_o_update) &&
(((HEADER *)buf2)->opcode == ns_o_update) )
return (1);
if (qdcount != ntohs(((HEADER*)buf2)->qdcount)) if (qdcount != ntohs(((HEADER*)buf2)->qdcount))
return (0); return (0);
while (qdcount-- > 0) { while (qdcount-- > 0) {
char tname[MAXDNAME+1]; char tname[MAXDNAME+1];
register int n, ttype, tclass; int n, ttype, tclass;
n = dn_expand(buf1, eom1, cp, tname, sizeof tname); n = dn_expand(buf1, eom1, cp, tname, sizeof tname);
if (n < 0) if (n < 0)
@ -263,8 +287,8 @@ res_queriesmatch(buf1, eom1, buf2, eom2)
cp += n; cp += n;
if (cp + 2 * INT16SZ > eom1) if (cp + 2 * INT16SZ > eom1)
return (-1); return (-1);
ttype = _getshort(cp); cp += INT16SZ; ttype = ns_get16(cp); cp += INT16SZ;
tclass = _getshort(cp); cp += INT16SZ; tclass = ns_get16(cp); cp += INT16SZ;
if (!res_nameinquery(tname, ttype, tclass, buf2, eom2)) if (!res_nameinquery(tname, ttype, tclass, buf2, eom2))
return (0); return (0);
} }
@ -280,9 +304,8 @@ res_send(buf, buflen, ans, anssiz)
{ {
HEADER *hp = (HEADER *) buf; HEADER *hp = (HEADER *) buf;
HEADER *anhp = (HEADER *) ans; HEADER *anhp = (HEADER *) ans;
int gotsomewhere, connreset, terrno, try, v_circuit, resplen, ns; int gotsomewhere, connreset, terrno, try, v_circuit, resplen, ns, n;
register int n; u_int badns; /* XXX NSMAX can't exceed #/bits in this variable */
u_int badns; /* XXX NSMAX can't exceed #/bits in this var */
if ((_res.options & RES_INIT) == 0 && res_init() == -1) { if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
/* errno should have been set by res_init() in this case. */ /* errno should have been set by res_init() in this case. */
@ -358,7 +381,7 @@ res_send(buf, buflen, ans, anssiz)
*/ */
try = _res.retry; try = _res.retry;
truncated = 0; truncated = 0;
if ((s < 0) || (!vc)) { if (s < 0 || !vc || hp->opcode == ns_o_update) {
if (s >= 0) if (s >= 0)
res_close(); res_close();
@ -370,7 +393,7 @@ res_send(buf, buflen, ans, anssiz)
} }
errno = 0; errno = 0;
if (connect(s, (struct sockaddr *)nsap, if (connect(s, (struct sockaddr *)nsap,
sizeof(struct sockaddr)) < 0) { sizeof *nsap) < 0) {
terrno = errno; terrno = errno;
Aerror(stderr, "connect/vc", Aerror(stderr, "connect/vc",
errno, *nsap); errno, *nsap);
@ -427,7 +450,7 @@ res_send(buf, buflen, ans, anssiz)
res_close(); res_close();
goto next_ns; goto next_ns;
} }
resplen = _getshort(ans); resplen = ns_get16(ans);
if (resplen > anssiz) { if (resplen > anssiz) {
Dprint(_res.options & RES_DEBUG, Dprint(_res.options & RES_DEBUG,
(stdout, ";; response truncated\n") (stdout, ";; response truncated\n")
@ -509,7 +532,7 @@ res_send(buf, buflen, ans, anssiz)
res_close(); res_close();
s = socket(PF_INET, SOCK_DGRAM, 0); s = socket(PF_INET, SOCK_DGRAM, 0);
if (s < 0) { if (s < 0) {
#if !CAN_RECONNECT #ifndef CAN_RECONNECT
bad_dg_sock: bad_dg_sock:
#endif #endif
terrno = errno; terrno = errno;
@ -518,6 +541,7 @@ res_send(buf, buflen, ans, anssiz)
} }
connected = 0; connected = 0;
} }
#ifndef CANNOT_CONNECT_DGRAM
/* /*
* On a 4.3BSD+ machine (client and server, * On a 4.3BSD+ machine (client and server,
* actually), sending to a nameserver datagram * actually), sending to a nameserver datagram
@ -540,7 +564,7 @@ res_send(buf, buflen, ans, anssiz)
*/ */
if (!connected) { if (!connected) {
if (connect(s, (struct sockaddr *)nsap, if (connect(s, (struct sockaddr *)nsap,
sizeof(struct sockaddr) sizeof *nsap
) < 0) { ) < 0) {
Aerror(stderr, Aerror(stderr,
"connect(dg)", "connect(dg)",
@ -563,7 +587,7 @@ res_send(buf, buflen, ans, anssiz)
* for responses from more than one server. * for responses from more than one server.
*/ */
if (connected) { if (connected) {
#if CAN_RECONNECT #ifdef CAN_RECONNECT
struct sockaddr_in no_addr; struct sockaddr_in no_addr;
no_addr.sin_family = AF_INET; no_addr.sin_family = AF_INET;
@ -572,7 +596,7 @@ res_send(buf, buflen, ans, anssiz)
(void) connect(s, (void) connect(s,
(struct sockaddr *) (struct sockaddr *)
&no_addr, &no_addr,
sizeof(no_addr)); sizeof no_addr);
#else #else
int s1 = socket(PF_INET, SOCK_DGRAM,0); int s1 = socket(PF_INET, SOCK_DGRAM,0);
if (s1 < 0) if (s1 < 0)
@ -581,20 +605,23 @@ res_send(buf, buflen, ans, anssiz)
(void) close(s1); (void) close(s1);
Dprint(_res.options & RES_DEBUG, Dprint(_res.options & RES_DEBUG,
(stdout, ";; new DG socket\n")) (stdout, ";; new DG socket\n"))
#endif #endif /* CAN_RECONNECT */
connected = 0; connected = 0;
errno = 0; errno = 0;
} }
#endif /* !CANNOT_CONNECT_DGRAM */
if (sendto(s, (char*)buf, buflen, 0, if (sendto(s, (char*)buf, buflen, 0,
(struct sockaddr *)nsap, (struct sockaddr *)nsap,
sizeof(struct sockaddr)) sizeof *nsap)
!= buflen) { != buflen) {
Aerror(stderr, "sendto", errno, *nsap); Aerror(stderr, "sendto", errno, *nsap);
badns |= (1 << ns); badns |= (1 << ns);
res_close(); res_close();
goto next_ns; goto next_ns;
} }
#ifndef CANNOT_CONNECT_DGRAM
} }
#endif /* !CANNOT_CONNECT_DGRAM */
/* /*
* Wait for reply * Wait for reply
@ -723,7 +750,7 @@ res_send(buf, buflen, ans, anssiz)
ans, (resplen>anssiz)?anssiz:resplen); ans, (resplen>anssiz)?anssiz:resplen);
goto wait; goto wait;
} }
#if CHECK_SRVR_ADDR #ifdef CHECK_SRVR_ADDR
if (!(_res.options & RES_INSECURE1) && if (!(_res.options & RES_INSECURE1) &&
!res_isourserver(&from)) { !res_isourserver(&from)) {
/* /*
@ -830,12 +857,12 @@ res_send(buf, buflen, ans, anssiz)
} /*foreach ns*/ } /*foreach ns*/
} /*foreach retry*/ } /*foreach retry*/
res_close(); res_close();
if (!v_circuit) if (!v_circuit) {
if (!gotsomewhere) if (!gotsomewhere)
errno = ECONNREFUSED; /* no nameservers found */ errno = ECONNREFUSED; /* no nameservers found */
else else
errno = ETIMEDOUT; /* no answer obtained */ errno = ETIMEDOUT; /* no answer obtained */
else } else
errno = terrno; errno = terrno;
return (-1); return (-1);
} }

View File

@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE. * SUCH DAMAGE.
* *
* $Id: res_stubs.c,v 1.5 1997/02/22 15:00:36 peter Exp $ * $Id: res_stubs.c,v 1.6 1997/06/27 08:35:13 peter Exp $
*/ */
/* /*
@ -41,6 +41,21 @@
#include <sys/types.h> #include <sys/types.h>
#include <sys/cdefs.h> #include <sys/cdefs.h>
__weak_reference(__inet_addr, inet_addr);
__weak_reference(__inet_aton, inet_aton);
__weak_reference(__inet_lnaof, inet_lnaof);
__weak_reference(__inet_makeaddr, inet_makeaddr);
__weak_reference(__inet_neta, inet_neta);
__weak_reference(__inet_netof, inet_netof);
__weak_reference(__inet_network, inet_network);
__weak_reference(__inet_net_ntop, inet_net_ntop);
__weak_reference(__inet_net_pton, inet_net_pton);
__weak_reference(__inet_ntoa, inet_ntoa);
__weak_reference(__inet_pton, inet_pton);
__weak_reference(__inet_ntop, inet_ntop);
__weak_reference(__inet_nsap_addr, inet_nsap_addr);
__weak_reference(__inet_nsap_ntoa, inet_nsap_ntoa);
__weak_reference(__sym_ston, sym_ston); __weak_reference(__sym_ston, sym_ston);
__weak_reference(__sym_ntos, sym_ntos); __weak_reference(__sym_ntos, sym_ntos);
__weak_reference(__sym_ntop, sym_ntop); __weak_reference(__sym_ntop, sym_ntop);
@ -51,7 +66,6 @@ __weak_reference(__p_secstodate, p_secstodate);
__weak_reference(__dn_count_labels, dn_count_labels); __weak_reference(__dn_count_labels, dn_count_labels);
__weak_reference(__dn_comp, dn_comp); __weak_reference(__dn_comp, dn_comp);
__weak_reference(__res_close, _res_close); __weak_reference(__res_close, _res_close);
#ifdef BIND_RES_POSIX3
__weak_reference(__dn_expand, dn_expand); __weak_reference(__dn_expand, dn_expand);
__weak_reference(__res_init, res_init); __weak_reference(__res_init, res_init);
__weak_reference(__res_query, res_query); __weak_reference(__res_query, res_query);
@ -59,6 +73,3 @@ __weak_reference(__res_search, res_search);
__weak_reference(__res_querydomain, res_querydomain); __weak_reference(__res_querydomain, res_querydomain);
__weak_reference(__res_mkquery, res_mkquery); __weak_reference(__res_mkquery, res_mkquery);
__weak_reference(__res_send, res_send); __weak_reference(__res_send, res_send);
#else
__weak_reference(res_send, __res_send);
#endif

516
lib/libc/net/res_update.c Normal file
View File

@ -0,0 +1,516 @@
#if !defined(lint) && !defined(SABER)
static char rcsid[] = "$Id: res_update.c,v 1.14 1998/03/10 22:04:48 halley Exp $";
#endif /* not lint */
/*
* Copyright (c) 1996 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.
*/
/*
* Based on the Dynamic DNS reference implementation by Viraj Bais
* <viraj_bais@ccm.fm.intel.com>
*/
#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 <errno.h>
#include <limits.h>
#include <netdb.h>
#include <resolv.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/*
* Separate a linked list of records into groups so that all records
* in a group will belong to a single zone on the nameserver.
* Create a dynamic update packet for each zone and send it to the
* nameservers for that zone, and await answer.
* Abort if error occurs in updating any zone.
* Return the number of zones updated on success, < 0 on error.
*
* On error, caller must deal with the unsynchronized zones
* eg. an A record might have been successfully added to the forward
* zone but the corresponding PTR record would be missing if error
* was encountered while updating the reverse zone.
*/
#define NSMAX 16
struct ns1 {
char nsname[MAXDNAME];
struct in_addr nsaddr1;
};
struct zonegrp {
char z_origin[MAXDNAME];
int16_t z_class;
char z_soardata[MAXDNAME + 5 * INT32SZ];
struct ns1 z_ns[NSMAX];
int z_nscount;
ns_updrec * z_rr;
struct zonegrp *z_next;
};
int
res_update(ns_updrec *rrecp_in) {
ns_updrec *rrecp, *tmprrecp;
u_char buf[PACKETSZ], answer[PACKETSZ], packet[2*PACKETSZ];
char name[MAXDNAME], zname[MAXDNAME], primary[MAXDNAME],
mailaddr[MAXDNAME];
u_char soardata[2*MAXCDNAME+5*INT32SZ];
char *dname, *svdname, *cp1, *target;
u_char *cp, *eom;
HEADER *hp = (HEADER *) answer;
struct zonegrp *zptr = NULL, *tmpzptr, *prevzptr, *zgrp_start = NULL;
int i, j, k = 0, n, ancount, nscount, arcount, rcode, rdatasize,
newgroup, done, myzone, seen_before, numzones = 0;
u_int16_t dlen, class, qclass, type, qtype;
u_int32_t ttl;
if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
h_errno = NETDB_INTERNAL;
return (-1);
}
for (rrecp = rrecp_in; rrecp; rrecp = rrecp->r_next) {
dname = rrecp->r_dname;
n = strlen(dname);
if (dname[n-1] == '.')
dname[n-1] = '\0';
qtype = T_SOA;
qclass = rrecp->r_class;
done = 0;
seen_before = 0;
while (!done && dname) {
if (qtype == T_SOA) {
for (tmpzptr = zgrp_start;
tmpzptr && !seen_before;
tmpzptr = tmpzptr->z_next) {
if (strcasecmp(dname,
tmpzptr->z_origin) == 0 &&
tmpzptr->z_class == qclass)
seen_before++;
for (tmprrecp = tmpzptr->z_rr;
tmprrecp && !seen_before;
tmprrecp = tmprrecp->r_grpnext)
if (strcasecmp(dname, tmprrecp->r_dname) == 0
&& tmprrecp->r_class == qclass) {
seen_before++;
break;
}
if (seen_before) {
/*
* Append to the end of
* current group.
*/
for (tmprrecp = tmpzptr->z_rr;
tmprrecp->r_grpnext;
tmprrecp = tmprrecp->r_grpnext)
(void)NULL;
tmprrecp->r_grpnext = rrecp;
rrecp->r_grpnext = NULL;
done = 1;
break;
}
}
} else if (qtype == T_A) {
for (tmpzptr = zgrp_start;
tmpzptr && !done;
tmpzptr = tmpzptr->z_next)
for (i = 0; i < tmpzptr->z_nscount; i++)
if (tmpzptr->z_class == qclass &&
strcasecmp(tmpzptr->z_ns[i].nsname,
dname) == 0 &&
tmpzptr->z_ns[i].nsaddr1.s_addr != 0) {
zptr->z_ns[k].nsaddr1.s_addr =
tmpzptr->z_ns[i].nsaddr1.s_addr;
done = 1;
break;
}
}
if (done)
break;
n = res_mkquery(QUERY, dname, qclass, qtype, NULL,
0, NULL, buf, sizeof buf);
if (n <= 0) {
fprintf(stderr, "res_update: mkquery failed\n");
return (n);
}
n = res_send(buf, n, answer, sizeof answer);
if (n < 0) {
fprintf(stderr, "res_update: send error for %s\n",
rrecp->r_dname);
return (n);
}
if (n < HFIXEDSZ)
return (-1);
ancount = ntohs(hp->ancount);
nscount = ntohs(hp->nscount);
arcount = ntohs(hp->arcount);
rcode = hp->rcode;
cp = answer + HFIXEDSZ;
eom = answer + n;
/* skip the question section */
n = dn_skipname(cp, eom);
if (n < 0 || cp + n + 2 * INT16SZ > eom)
return (-1);
cp += n + 2 * INT16SZ;
if (qtype == T_SOA) {
if (ancount == 0 && nscount == 0 && arcount == 0) {
/*
* if (rcode == NOERROR) then the dname exists but
* has no soa record associated with it.
* if (rcode == NXDOMAIN) then the dname does not
* exist and the server is replying out of NCACHE.
* in either case, proceed with the next try
*/
dname = strchr(dname, '.');
if (dname != NULL)
dname++;
continue;
} else if ((rcode == NOERROR || rcode == NXDOMAIN) &&
ancount == 0 &&
nscount == 1 && arcount == 0) {
/*
* name/data does not exist, soa record supplied in the
* authority section
*/
/* authority section must contain the soa record */
if ((n = dn_expand(answer, eom, cp, zname,
sizeof zname)) < 0)
return (n);
cp += n;
if (cp + 2 * INT16SZ > eom)
return (-1);
GETSHORT(type, cp);
GETSHORT(class, cp);
if (type != T_SOA || class != qclass) {
fprintf(stderr, "unknown answer\n");
return (-1);
}
myzone = 0;
svdname = dname;
while (dname)
if (strcasecmp(dname, zname) == 0) {
myzone = 1;
break;
} else if ((dname = strchr(dname, '.')) != NULL)
dname++;
if (!myzone) {
dname = strchr(svdname, '.');
if (dname != NULL)
dname++;
continue;
}
nscount = 0;
/* fallthrough */
} else if (rcode == NOERROR && ancount == 1) {
/*
* found the zone name
* new servers will supply NS records for the zone
* in authority section and A records for those
* nameservers in the additional section
* older servers have to be explicitly queried for
* NS records for the zone
*/
/* answer section must contain the soa record */
if ((n = dn_expand(answer, eom, cp, zname,
sizeof zname)) < 0)
return (n);
else
cp += n;
if (cp + 2 * INT16SZ > eom)
return (-1);
GETSHORT(type, cp);
GETSHORT(class, cp);
if (type == T_CNAME) {
dname = strchr(dname, '.');
if (dname != NULL)
dname++;
continue;
}
if (strcasecmp(dname, zname) != 0 ||
type != T_SOA ||
class != rrecp->r_class) {
fprintf(stderr, "unknown answer\n");
return (-1);
}
/* FALLTHROUGH */
} else {
fprintf(stderr,
"unknown response: ans=%d, auth=%d, add=%d, rcode=%d\n",
ancount, nscount, arcount, hp->rcode);
return (-1);
}
if (cp + INT32SZ + INT16SZ > eom)
return (-1);
/* continue processing the soa record */
GETLONG(ttl, cp);
GETSHORT(dlen, cp);
if (cp + dlen > eom)
return (-1);
newgroup = 1;
zptr = zgrp_start;
prevzptr = NULL;
while (zptr) {
if (strcasecmp(zname, zptr->z_origin) == 0 &&
type == T_SOA && class == qclass) {
newgroup = 0;
break;
}
prevzptr = zptr;
zptr = zptr->z_next;
}
if (!newgroup) {
for (tmprrecp = zptr->z_rr;
tmprrecp->r_grpnext;
tmprrecp = tmprrecp->r_grpnext)
;
tmprrecp->r_grpnext = rrecp;
rrecp->r_grpnext = NULL;
done = 1;
cp += dlen;
break;
} else {
if ((n = dn_expand(answer, eom, cp, primary,
sizeof primary)) < 0)
return (n);
cp += n;
/*
* We don't have to bounds check here because the
* next use of 'cp' is in dn_expand().
*/
cp1 = (char *)soardata;
strcpy(cp1, primary);
cp1 += strlen(cp1) + 1;
if ((n = dn_expand(answer, eom, cp, mailaddr,
sizeof mailaddr)) < 0)
return (n);
cp += n;
strcpy(cp1, mailaddr);
cp1 += strlen(cp1) + 1;
if (cp + 5*INT32SZ > eom)
return (-1);
memcpy(cp1, cp, 5*INT32SZ);
cp += 5*INT32SZ;
cp1 += 5*INT32SZ;
rdatasize = (u_char *)cp1 - soardata;
zptr = calloc(1, sizeof(struct zonegrp));
if (zptr == NULL)
return (-1);
if (zgrp_start == NULL)
zgrp_start = zptr;
else
prevzptr->z_next = zptr;
zptr->z_rr = rrecp;
rrecp->r_grpnext = NULL;
strcpy(zptr->z_origin, zname);
zptr->z_class = class;
memcpy(zptr->z_soardata, soardata, rdatasize);
/* fallthrough to process NS and A records */
}
} else if (qtype == T_NS) {
if (rcode == NOERROR && ancount > 0) {
strcpy(zname, dname);
for (zptr = zgrp_start; zptr; zptr = zptr->z_next) {
if (strcasecmp(zname, zptr->z_origin) == 0)
break;
}
if (zptr == NULL)
/* should not happen */
return (-1);
if (nscount > 0) {
/*
* answer and authority sections contain
* the same information, skip answer section
*/
for (j = 0; j < ancount; j++) {
n = dn_skipname(cp, eom);
if (n < 0)
return (-1);
n += 2*INT16SZ + INT32SZ;
if (cp + n + INT16SZ > eom)
return (-1);
cp += n;
GETSHORT(dlen, cp);
cp += dlen;
}
} else
nscount = ancount;
/* fallthrough to process NS and A records */
} else {
fprintf(stderr, "cannot determine nameservers for %s:\
ans=%d, auth=%d, add=%d, rcode=%d\n",
dname, ancount, nscount, arcount, hp->rcode);
return (-1);
}
} else if (qtype == T_A) {
if (rcode == NOERROR && ancount > 0) {
arcount = ancount;
ancount = nscount = 0;
/* fallthrough to process A records */
} else {
fprintf(stderr, "cannot determine address for %s:\
ans=%d, auth=%d, add=%d, rcode=%d\n",
dname, ancount, nscount, arcount, hp->rcode);
return (-1);
}
}
/* process NS records for the zone */
j = 0;
for (i = 0; i < nscount; i++) {
if ((n = dn_expand(answer, eom, cp, name,
sizeof name)) < 0)
return (n);
cp += n;
if (cp + 3 * INT16SZ + INT32SZ > eom)
return (-1);
GETSHORT(type, cp);
GETSHORT(class, cp);
GETLONG(ttl, cp);
GETSHORT(dlen, cp);
if (cp + dlen > eom)
return (-1);
if (strcasecmp(name, zname) == 0 &&
type == T_NS && class == qclass) {
if ((n = dn_expand(answer, eom, cp,
name, sizeof name)) < 0)
return (n);
target = zptr->z_ns[j++].nsname;
strcpy(target, name);
}
cp += dlen;
}
if (zptr->z_nscount == 0)
zptr->z_nscount = j;
/* get addresses for the nameservers */
for (i = 0; i < arcount; i++) {
if ((n = dn_expand(answer, eom, cp, name,
sizeof name)) < 0)
return (n);
cp += n;
if (cp + 3 * INT16SZ + INT32SZ > eom)
return (-1);
GETSHORT(type, cp);
GETSHORT(class, cp);
GETLONG(ttl, cp);
GETSHORT(dlen, cp);
if (cp + dlen > eom)
return (-1);
if (type == T_A && dlen == INT32SZ && class == qclass) {
for (j = 0; j < zptr->z_nscount; j++)
if (strcasecmp(name, zptr->z_ns[j].nsname) == 0) {
memcpy(&zptr->z_ns[j].nsaddr1.s_addr, cp,
INT32SZ);
break;
}
}
cp += dlen;
}
if (zptr->z_nscount == 0) {
dname = zname;
qtype = T_NS;
continue;
}
done = 1;
for (k = 0; k < zptr->z_nscount; k++)
if (zptr->z_ns[k].nsaddr1.s_addr == 0) {
done = 0;
dname = zptr->z_ns[k].nsname;
qtype = T_A;
}
} /* while */
}
_res.options |= RES_DEBUG;
for (zptr = zgrp_start; zptr; zptr = zptr->z_next) {
/* append zone section */
rrecp = res_mkupdrec(ns_s_zn, zptr->z_origin,
zptr->z_class, ns_t_soa, 0);
if (rrecp == NULL) {
fprintf(stderr, "saverrec error\n");
fflush(stderr);
return (-1);
}
rrecp->r_grpnext = zptr->z_rr;
zptr->z_rr = rrecp;
n = res_mkupdate(zptr->z_rr, packet, sizeof packet);
if (n < 0) {
fprintf(stderr, "res_mkupdate error\n");
fflush(stderr);
return (-1);
} else
fprintf(stdout, "res_mkupdate: packet size = %d\n", n);
/*
* Override the list of NS records from res_init() with
* the authoritative nameservers for the zone being updated.
* Sort primary to be the first in the list of nameservers.
*/
for (i = 0; i < zptr->z_nscount; i++) {
if (strcasecmp(zptr->z_ns[i].nsname,
zptr->z_soardata) == 0) {
struct in_addr tmpaddr;
if (i != 0) {
strcpy(zptr->z_ns[i].nsname,
zptr->z_ns[0].nsname);
strcpy(zptr->z_ns[0].nsname,
zptr->z_soardata);
tmpaddr = zptr->z_ns[i].nsaddr1;
zptr->z_ns[i].nsaddr1 =
zptr->z_ns[0].nsaddr1;
zptr->z_ns[0].nsaddr1 = tmpaddr;
}
break;
}
}
for (i = 0; i < MAXNS; i++) {
_res.nsaddr_list[i].sin_addr = zptr->z_ns[i].nsaddr1;
_res.nsaddr_list[i].sin_family = AF_INET;
_res.nsaddr_list[i].sin_port = htons(NAMESERVER_PORT);
}
_res.nscount = (zptr->z_nscount < MAXNS) ?
zptr->z_nscount : MAXNS;
n = res_send(packet, n, answer, sizeof(answer));
if (n < 0) {
fprintf(stderr, "res_send: send error, n=%d\n", n);
break;
} else
numzones++;
}
/* free malloc'ed memory */
while(zgrp_start) {
zptr = zgrp_start;
zgrp_start = zgrp_start->z_next;
res_freeupdrec(zptr->z_rr); /* Zone section we allocated. */
free((char *)zptr);
}
return (numzones);
}