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:
parent
a28ce30ec5
commit
14b93edab3
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=36891
@ -1,5 +1,5 @@
|
||||
# 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
|
||||
.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 \
|
||||
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_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 \
|
||||
res_init.c res_mkquery.c res_query.c res_send.c res_stubs.c \
|
||||
send.c
|
||||
res_init.c res_mkquery.c res_mkupdate.c res_query.c res_send.c \
|
||||
res_stubs.c res_update.c send.c
|
||||
# not supported: iso_addr.c
|
||||
|
||||
# machine-dependent net sources
|
||||
|
@ -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
|
||||
* 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 !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/param.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <arpa/nameser.h>
|
||||
@ -50,13 +55,8 @@
|
||||
#include <ctype.h>
|
||||
#include <resolv.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#if defined(BSD) && (BSD >= 199103) && defined(AF_INET6)
|
||||
# include <stdlib.h>
|
||||
# include <string.h>
|
||||
#else
|
||||
# include "../conf/portability.h"
|
||||
#endif
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#define Assert(Cond) if (!(Cond)) abort()
|
||||
|
||||
@ -128,16 +128,11 @@ static const char Pad64 = '=';
|
||||
*/
|
||||
|
||||
int
|
||||
b64_ntop(src, srclength, target, targsize)
|
||||
u_char const *src;
|
||||
size_t srclength;
|
||||
char *target;
|
||||
size_t targsize;
|
||||
{
|
||||
b64_ntop(u_char const *src, size_t srclength, char *target, size_t targsize) {
|
||||
size_t datalength = 0;
|
||||
u_char input[3];
|
||||
u_char output[4];
|
||||
int i;
|
||||
size_t i;
|
||||
|
||||
while (2 < srclength) {
|
||||
input[0] = *src++;
|
||||
@ -224,7 +219,7 @@ b64_pton(src, target, targsize)
|
||||
switch (state) {
|
||||
case 0:
|
||||
if (target) {
|
||||
if (tarindex >= targsize)
|
||||
if ((size_t)tarindex >= targsize)
|
||||
return (-1);
|
||||
target[tarindex] = (pos - Base64) << 2;
|
||||
}
|
||||
@ -232,7 +227,7 @@ b64_pton(src, target, targsize)
|
||||
break;
|
||||
case 1:
|
||||
if (target) {
|
||||
if (tarindex + 1 >= targsize)
|
||||
if ((size_t)tarindex + 1 >= targsize)
|
||||
return (-1);
|
||||
target[tarindex] |= (pos - Base64) >> 4;
|
||||
target[tarindex+1] = ((pos - Base64) & 0x0f)
|
||||
@ -243,7 +238,7 @@ b64_pton(src, target, targsize)
|
||||
break;
|
||||
case 2:
|
||||
if (target) {
|
||||
if (tarindex + 1 >= targsize)
|
||||
if ((size_t)tarindex + 1 >= targsize)
|
||||
return (-1);
|
||||
target[tarindex] |= (pos - Base64) >> 2;
|
||||
target[tarindex+1] = ((pos - Base64) & 0x03)
|
||||
@ -254,7 +249,7 @@ b64_pton(src, target, targsize)
|
||||
break;
|
||||
case 3:
|
||||
if (target) {
|
||||
if (tarindex >= targsize)
|
||||
if ((size_t)tarindex >= targsize)
|
||||
return (-1);
|
||||
target[tarindex] |= (pos - Base64);
|
||||
}
|
||||
@ -280,7 +275,7 @@ b64_pton(src, target, targsize)
|
||||
|
||||
case 2: /* Valid, means one byte of info */
|
||||
/* Skip any number of spaces. */
|
||||
for (NULL; ch != '\0'; ch = *src++)
|
||||
for ((void)NULL; ch != '\0'; ch = *src++)
|
||||
if (!isspace(ch))
|
||||
break;
|
||||
/* 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
|
||||
* whitespace after it?
|
||||
*/
|
||||
for (NULL; ch != '\0'; ch = *src++)
|
||||
for ((void)NULL; ch != '\0'; ch = *src++)
|
||||
if (!isspace(ch))
|
||||
return (-1);
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
/*-
|
||||
/*
|
||||
* Copyright (c) 1987, 1993
|
||||
* 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
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* 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
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies, and that
|
||||
* 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.
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
|
||||
* 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
|
||||
* 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.
|
||||
* -
|
||||
* --Copyright--
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
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 */
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/uio.h>
|
||||
#include <netdb.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
const char *h_errlist[] = {
|
||||
"Resolver Error 0 (no error)",
|
||||
@ -71,7 +68,7 @@ const char *h_errlist[] = {
|
||||
};
|
||||
int h_nerr = { sizeof h_errlist / sizeof h_errlist[0] };
|
||||
|
||||
extern int h_errno;
|
||||
int h_errno;
|
||||
|
||||
/*
|
||||
* herror --
|
||||
|
@ -16,8 +16,8 @@
|
||||
*/
|
||||
|
||||
#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 rcsid[] = "$Id$";
|
||||
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: inet_net_pton.c,v 1.3 1997/02/22 15:00:18 peter Exp $";
|
||||
#endif
|
||||
|
||||
#include <sys/types.h>
|
||||
@ -159,8 +159,7 @@ inet_net_pton_ipv4(src, dst, size)
|
||||
assert(n >= 0 && n <= 9);
|
||||
bits *= 10;
|
||||
bits += n;
|
||||
} while ((ch = *src++) != '\0' &&
|
||||
isascii(ch) && isdigit(ch));
|
||||
} while ((ch = *src++) != '\0' && isascii(ch) && isdigit(ch));
|
||||
if (ch != '\0')
|
||||
goto enoent;
|
||||
if (bits > 32)
|
||||
|
@ -49,10 +49,9 @@ u_long
|
||||
inet_network(cp)
|
||||
register const char *cp;
|
||||
{
|
||||
register u_long val, base, n;
|
||||
register u_long val, base, n, i;
|
||||
register char c;
|
||||
u_long parts[4], *pp = parts;
|
||||
register int i;
|
||||
|
||||
again:
|
||||
val = 0; base = 10;
|
||||
@ -60,7 +59,7 @@ inet_network(cp)
|
||||
base = 8, cp++;
|
||||
if (*cp == 'x' || *cp == 'X')
|
||||
base = 16, cp++;
|
||||
while ( (c = *cp) ) {
|
||||
while ((c = *cp) != 0) {
|
||||
if (isdigit(c)) {
|
||||
val = (val * base) + (c - '0');
|
||||
cp++;
|
||||
|
@ -35,25 +35,23 @@
|
||||
static char sccsid[] = "@(#)inet_ntoa.c 8.1 (Berkeley) 6/4/93";
|
||||
#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/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <stdio.h>
|
||||
|
||||
/*
|
||||
* Convert network-format internet address
|
||||
* to base 256 d.d.d.d representation.
|
||||
*/
|
||||
char *
|
||||
inet_ntoa(in)
|
||||
struct in_addr in;
|
||||
{
|
||||
static char b[18];
|
||||
register char *p;
|
||||
static char ret[18];
|
||||
|
||||
p = (char *)∈
|
||||
#define UC(b) (((int)b)&0xff)
|
||||
(void)snprintf(b, sizeof(b),
|
||||
"%d.%d.%d.%d", UC(p[0]), UC(p[1]), UC(p[2]), UC(p[3]));
|
||||
return (b);
|
||||
strcpy(ret, "[inet_ntoa error]");
|
||||
(void) inet_ntop(AF_INET, &in, ret, sizeof ret);
|
||||
return (ret);
|
||||
}
|
||||
|
@ -15,7 +15,7 @@
|
||||
*/
|
||||
|
||||
#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 */
|
||||
|
||||
#include <sys/param.h>
|
||||
@ -24,9 +24,9 @@ static char rcsid[] = "$Id$";
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <arpa/nameser.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#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;
|
||||
struct { int base, len; } best, cur;
|
||||
u_int words[IN6ADDRSZ / INT16SZ];
|
||||
u_int words[NS_IN6ADDRSZ / NS_INT16SZ];
|
||||
int i;
|
||||
|
||||
/*
|
||||
@ -123,11 +123,11 @@ inet_ntop6(src, dst, size)
|
||||
* Find the longest run of 0x00's in src[] for :: shorthanding.
|
||||
*/
|
||||
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));
|
||||
best.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 (cur.base == -1)
|
||||
cur.base = i, cur.len = 1;
|
||||
@ -152,7 +152,7 @@ inet_ntop6(src, dst, size)
|
||||
* Format the result.
|
||||
*/
|
||||
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? */
|
||||
if (best.base != -1 && i >= best.base &&
|
||||
i < (best.base + best.len)) {
|
||||
@ -174,7 +174,8 @@ inet_ntop6(src, dst, size)
|
||||
tp += SPRINTF((tp, "%x", words[i]));
|
||||
}
|
||||
/* 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++ = '\0';
|
||||
|
||||
|
@ -15,7 +15,7 @@
|
||||
*/
|
||||
|
||||
#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 */
|
||||
|
||||
#include <sys/param.h>
|
||||
@ -81,7 +81,7 @@ inet_pton4(src, dst)
|
||||
{
|
||||
static const char digits[] = "0123456789";
|
||||
int saw_digit, octets, ch;
|
||||
u_char tmp[INADDRSZ], *tp;
|
||||
u_char tmp[NS_INADDRSZ], *tp;
|
||||
|
||||
saw_digit = 0;
|
||||
octets = 0;
|
||||
@ -111,7 +111,7 @@ inet_pton4(src, dst)
|
||||
if (octets < 4)
|
||||
return (0);
|
||||
|
||||
memcpy(dst, tmp, INADDRSZ);
|
||||
memcpy(dst, tmp, NS_INADDRSZ);
|
||||
return (1);
|
||||
}
|
||||
|
||||
@ -135,13 +135,13 @@ inet_pton6(src, dst)
|
||||
{
|
||||
static const char xdigits_l[] = "0123456789abcdef",
|
||||
xdigits_u[] = "0123456789ABCDEF";
|
||||
u_char tmp[IN6ADDRSZ], *tp, *endp, *colonp;
|
||||
u_char tmp[NS_IN6ADDRSZ], *tp, *endp, *colonp;
|
||||
const char *xdigits, *curtok;
|
||||
int ch, saw_xdigit;
|
||||
u_int val;
|
||||
|
||||
memset((tp = tmp), '\0', IN6ADDRSZ);
|
||||
endp = tp + IN6ADDRSZ;
|
||||
memset((tp = tmp), '\0', NS_IN6ADDRSZ);
|
||||
endp = tp + NS_IN6ADDRSZ;
|
||||
colonp = NULL;
|
||||
/* Leading :: requires some special handling. */
|
||||
if (*src == ':')
|
||||
@ -171,7 +171,7 @@ inet_pton6(src, dst)
|
||||
colonp = tp;
|
||||
continue;
|
||||
}
|
||||
if (tp + INT16SZ > endp)
|
||||
if (tp + NS_INT16SZ > endp)
|
||||
return (0);
|
||||
*tp++ = (u_char) (val >> 8) & 0xff;
|
||||
*tp++ = (u_char) val & 0xff;
|
||||
@ -179,16 +179,16 @@ inet_pton6(src, dst)
|
||||
val = 0;
|
||||
continue;
|
||||
}
|
||||
if (ch == '.' && ((tp + INADDRSZ) <= endp) &&
|
||||
if (ch == '.' && ((tp + NS_INADDRSZ) <= endp) &&
|
||||
inet_pton4(curtok, tp) > 0) {
|
||||
tp += INADDRSZ;
|
||||
tp += NS_INADDRSZ;
|
||||
saw_xdigit = 0;
|
||||
break; /* '\0' was seen by inet_pton4(). */
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
if (saw_xdigit) {
|
||||
if (tp + INT16SZ > endp)
|
||||
if (tp + NS_INT16SZ > endp)
|
||||
return (0);
|
||||
*tp++ = (u_char) (val >> 8) & 0xff;
|
||||
*tp++ = (u_char) val & 0xff;
|
||||
@ -209,6 +209,6 @@ inet_pton6(src, dst)
|
||||
}
|
||||
if (tp != endp)
|
||||
return (0);
|
||||
memcpy(dst, tmp, IN6ADDRSZ);
|
||||
memcpy(dst, tmp, NS_IN6ADDRSZ);
|
||||
return (1);
|
||||
}
|
||||
|
593
lib/libc/net/ns_name.c
Normal file
593
lib/libc/net/ns_name.c
Normal 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
54
lib/libc/net/ns_netint.c
Normal 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
190
lib/libc/net/ns_parse.c
Normal 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
743
lib/libc/net/ns_print.c
Normal 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
151
lib/libc/net/ns_ttl.c
Normal 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);
|
||||
}
|
@ -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
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
@ -16,13 +16,14 @@
|
||||
*/
|
||||
|
||||
#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 */
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <arpa/nameser.h>
|
||||
#include <ctype.h>
|
||||
#include <resolv.h>
|
||||
@ -40,10 +41,10 @@ inet_nsap_addr(ascii, binary, maxlen)
|
||||
u_char *binary;
|
||||
int maxlen;
|
||||
{
|
||||
register u_char c, nib;
|
||||
u_char c, nib;
|
||||
u_int len = 0;
|
||||
|
||||
while ((c = *ascii++) != '\0' && len < maxlen) {
|
||||
while ((c = *ascii++) != '\0' && len < (u_int)maxlen) {
|
||||
if (c == '.' || c == '+' || c == '/')
|
||||
continue;
|
||||
if (!isascii(c))
|
||||
@ -52,7 +53,8 @@ inet_nsap_addr(ascii, binary, maxlen)
|
||||
c = toupper(c);
|
||||
if (isxdigit(c)) {
|
||||
nib = xtob(c);
|
||||
if ((c = *ascii++) != '\0') {
|
||||
c = *ascii++;
|
||||
if (c != '\0') {
|
||||
c = toupper(c);
|
||||
if (isxdigit(c)) {
|
||||
*binary++ = (nib << 4) | xtob(c);
|
||||
|
@ -1,6 +1,4 @@
|
||||
/*
|
||||
* ++Copyright++ 1985, 1993
|
||||
* -
|
||||
* Copyright (c) 1985, 1993
|
||||
* 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
|
||||
* 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
|
||||
@ -49,40 +49,42 @@
|
||||
* 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.
|
||||
* -
|
||||
* --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)
|
||||
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 rcsid[] = "$Id: res_comp.c,v 1.12 1997/06/27 08:22:02 peter 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.13 1998/05/02 13:10:56 peter Exp $";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/param.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/nameser.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <resolv.h>
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <unistd.h>
|
||||
#include <resolv.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
static int ns_name_ntop __P((const u_char *, char *, size_t));
|
||||
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 *));
|
||||
#define BIND_4_COMPAT
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
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;
|
||||
|
||||
if (ns_name_skip(&ptr, eom) == -1)
|
||||
@ -161,7 +163,7 @@ res_hnok(dn)
|
||||
int nch = *dn++;
|
||||
|
||||
if (periodchar(ch)) {
|
||||
NULL;
|
||||
(void)NULL;
|
||||
} else if (periodchar(pch)) {
|
||||
if (!borderchar(ch))
|
||||
return (0);
|
||||
@ -206,7 +208,7 @@ res_mailok(dn)
|
||||
|
||||
/* "." is a valid missing representation */
|
||||
if (*dn == '\0')
|
||||
return(1);
|
||||
return (1);
|
||||
|
||||
/* otherwise <label>.<hostname> */
|
||||
while ((ch = *dn++) != '\0') {
|
||||
@ -221,7 +223,7 @@ res_mailok(dn)
|
||||
}
|
||||
if (periodchar(ch))
|
||||
return (res_hnok(dn));
|
||||
return(0);
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -240,683 +242,17 @@ res_dnok(dn)
|
||||
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.
|
||||
*/
|
||||
|
||||
u_int16_t
|
||||
_getshort(msgp)
|
||||
register const u_char *msgp;
|
||||
{
|
||||
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. -- */
|
||||
void __putlong(u_int32_t src, u_char *dst) { ns_put32(src, dst); }
|
||||
void __putshort(u_int16_t src, u_char *dst) { ns_put16(src, dst); }
|
||||
u_int32_t _getlong(const u_char *src) { return (ns_get32(src)); }
|
||||
u_int16_t _getshort(const u_char *src) { return (ns_get16(src)); }
|
||||
#endif /*BIND_4_COMPAT*/
|
||||
|
@ -1,8 +1,8 @@
|
||||
#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 RFC1535 /* comply with RFC1535 (STRONGLY reccomended by vixie)*/
|
||||
#undef USELOOPBACK /* res_init() bind to localhost */
|
||||
#undef SUNSECURITY /* verify gethostbyaddr() calls - WE DONT NEED IT */
|
||||
#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 BIND_UPDATE 1 /* update support */
|
||||
|
@ -1,60 +1,22 @@
|
||||
/*
|
||||
* ++Copyright++ 1995
|
||||
* -
|
||||
* 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.
|
||||
*
|
||||
* Copyright (c) 1995,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, and that
|
||||
* 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
|
||||
* 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
|
||||
* 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.
|
||||
* -
|
||||
* --Copyright--
|
||||
*/
|
||||
|
||||
#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 */
|
||||
|
||||
#include <sys/types.h>
|
||||
@ -64,13 +26,14 @@ static char rcsid[] = "$Id$";
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <arpa/nameser.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <resolv.h>
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "res_config.h"
|
||||
|
||||
const char *_res_opcodes[] = {
|
||||
"QUERY",
|
||||
@ -78,15 +41,15 @@ const char *_res_opcodes[] = {
|
||||
"CQUERYM",
|
||||
"CQUERYU", /* experimental */
|
||||
"NOTIFY", /* experimental */
|
||||
"5",
|
||||
"UPDATE",
|
||||
"6",
|
||||
"7",
|
||||
"8",
|
||||
"UPDATEA",
|
||||
"UPDATED",
|
||||
"UPDATEDA",
|
||||
"UPDATEM",
|
||||
"UPDATEMA",
|
||||
"9",
|
||||
"10",
|
||||
"11",
|
||||
"12",
|
||||
"13",
|
||||
"ZONEINIT",
|
||||
"ZONEREF",
|
||||
};
|
||||
@ -98,14 +61,23 @@ const char *_res_resultcodes[] = {
|
||||
"NXDOMAIN",
|
||||
"NOTIMP",
|
||||
"REFUSED",
|
||||
"6",
|
||||
"7",
|
||||
"8",
|
||||
"9",
|
||||
"10",
|
||||
"YXDOMAIN",
|
||||
"YXRRSET",
|
||||
"NXRRSET",
|
||||
"NOTAUTH",
|
||||
"ZONEERR",
|
||||
"11",
|
||||
"12",
|
||||
"13",
|
||||
"14",
|
||||
"NOCHANGE",
|
||||
};
|
||||
|
||||
#ifdef BIND_UPDATE
|
||||
const char *_res_sectioncodes[] = {
|
||||
"ZONE",
|
||||
"PREREQUISITES",
|
||||
"UPDATE",
|
||||
"ADDITIONAL",
|
||||
};
|
||||
#endif
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,6 +1,4 @@
|
||||
/*
|
||||
* ++Copyright++ 1985, 1989, 1993
|
||||
* -
|
||||
* Copyright (c) 1985, 1989, 1993
|
||||
* 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
|
||||
* 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
|
||||
@ -49,14 +49,29 @@
|
||||
* 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.
|
||||
* -
|
||||
* --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)
|
||||
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 rcsid[] = "$Id: res_init.c,v 1.13 1997/06/27 08:22:03 peter 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.14 1997/09/01 01:19:20 brian Exp $";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#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 <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include "res_config.h"
|
||||
#include <arpa/nameser.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <resolv.h>
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "res_config.h"
|
||||
|
||||
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));
|
||||
#endif
|
||||
|
||||
#if !defined(isascii) /* XXX - could be a function */
|
||||
# define isascii(c) (!(c & 0200))
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Resolver state default settings.
|
||||
*/
|
||||
@ -94,6 +112,7 @@ struct __res_state _res
|
||||
# endif
|
||||
;
|
||||
|
||||
|
||||
/*
|
||||
* Set up default settings. If the configuration file exist, the values
|
||||
* there will have precedence. Otherwise, the server address is set to
|
||||
@ -376,7 +395,7 @@ res_init()
|
||||
printf(";;\t%s\n", *pp);
|
||||
printf(";;\t..END..\n");
|
||||
}
|
||||
#endif /* DEBUG */
|
||||
#endif
|
||||
#endif /* !RFC1535 */
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,4 @@
|
||||
/*
|
||||
* ++Copyright++ 1985, 1993
|
||||
* -
|
||||
* Copyright (c) 1985, 1993
|
||||
* 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
|
||||
* 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
|
||||
@ -49,28 +49,41 @@
|
||||
* 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.
|
||||
* -
|
||||
* --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)
|
||||
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 rcsid[] = "$Id$";
|
||||
static char orig_rcsid[] = "From: Id: res_mkquery.c,v 8.9 1997/04/24 22:22:36 vixie Exp $";
|
||||
static char rcsid[] = "$Id: res_mkquery.c,v 1.12 1997/02/22 15:00:33 peter Exp $";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/param.h>
|
||||
#include <netinet/in.h>
|
||||
|
||||
#include "res_config.h"
|
||||
#include <arpa/nameser.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <netdb.h>
|
||||
#include <resolv.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "res_config.h"
|
||||
|
||||
/*
|
||||
* 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))
|
||||
return (-1);
|
||||
bzero(buf, HFIXEDSZ);
|
||||
memset(buf, 0, HFIXEDSZ);
|
||||
hp = (HEADER *) buf;
|
||||
hp->id = htons(++_res.id);
|
||||
hp->opcode = op;
|
||||
@ -173,7 +186,7 @@ res_mkquery(op, dname, class, type, data, datalen, newrr_in, buf, buflen)
|
||||
__putshort(datalen, cp);
|
||||
cp += INT16SZ;
|
||||
if (datalen) {
|
||||
bcopy(data, cp, datalen);
|
||||
memcpy(cp, data, datalen);
|
||||
cp += datalen;
|
||||
}
|
||||
hp->ancount = htons(1);
|
||||
|
414
lib/libc/net/res_mkupdate.c
Normal file
414
lib/libc/net/res_mkupdate.c
Normal 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);
|
||||
}
|
@ -1,6 +1,4 @@
|
||||
/*
|
||||
* ++Copyright++ 1988, 1993
|
||||
* -
|
||||
* Copyright (c) 1988, 1993
|
||||
* 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
|
||||
* 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
|
||||
@ -49,41 +49,52 @@
|
||||
* 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.
|
||||
* -
|
||||
* --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)
|
||||
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 rcsid[] = "$Id: res_query.c,v 1.14 1997/06/27 08:22:03 peter 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.15 1997/09/01 01:19:21 brian Exp $";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/param.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include "res_config.h"
|
||||
#include <arpa/nameser.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <netdb.h>
|
||||
#include <resolv.h>
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <netdb.h>
|
||||
#include <resolv.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "res_config.h"
|
||||
|
||||
#if PACKETSZ > 1024
|
||||
#define MAXPACKET PACKETSZ
|
||||
#else
|
||||
#define MAXPACKET 1024
|
||||
#endif
|
||||
|
||||
const char *hostalias __P((const char *));
|
||||
int h_errno;
|
||||
|
||||
/*
|
||||
* Formulate a normal query, send, and await 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 */
|
||||
{
|
||||
u_char buf[MAXPACKET];
|
||||
register HEADER *hp = (HEADER *) answer;
|
||||
HEADER *hp = (HEADER *) answer;
|
||||
int n;
|
||||
|
||||
hp->rcode = NOERROR; /* default */
|
||||
@ -177,7 +188,7 @@ res_search(name, class, type, answer, anslen)
|
||||
u_char *answer; /* buffer to put answer */
|
||||
int anslen; /* size of answer */
|
||||
{
|
||||
register const char *cp, * const *domain;
|
||||
const char *cp, * const *domain;
|
||||
HEADER *hp = (HEADER *) answer;
|
||||
u_int dots;
|
||||
int trailing_dot, ret, saved_herrno;
|
||||
@ -196,10 +207,8 @@ res_search(name, class, type, answer, anslen)
|
||||
if (cp > name && *--cp == '.')
|
||||
trailing_dot++;
|
||||
|
||||
/*
|
||||
* if there aren't any dots, it could be a user-level alias
|
||||
*/
|
||||
if (!dots && (cp = __hostalias(name)) != NULL)
|
||||
/* If there aren't any dots, it could be a user-level alias */
|
||||
if (!dots && (cp = hostalias(name)) != NULL)
|
||||
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
|
||||
* 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 *
|
||||
hostalias(name)
|
||||
register const char *name;
|
||||
const char *name;
|
||||
{
|
||||
register char *cp1, *cp2;
|
||||
FILE *fp;
|
||||
@ -369,8 +379,7 @@ hostalias(name)
|
||||
|
||||
if (_res.options & RES_NOALIASES)
|
||||
return (NULL);
|
||||
/* XXX issetguid() would be better here, but we don't have that. */
|
||||
if (getuid() != geteuid() || getgid() != getegid())
|
||||
if (issetugid())
|
||||
return (NULL);
|
||||
file = getenv("HOSTALIASES");
|
||||
if (file == NULL || (fp = fopen(file, "r")) == NULL)
|
||||
|
@ -1,6 +1,4 @@
|
||||
/*
|
||||
* ++Copyright++ 1985, 1989, 1993
|
||||
* -
|
||||
* Copyright (c) 1985, 1989, 1993
|
||||
* 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
|
||||
* 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
|
||||
@ -49,14 +49,29 @@
|
||||
* 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.
|
||||
* -
|
||||
* --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)
|
||||
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 rcsid[] = "$Id: res_send.c,v 1.21 1998/05/02 13:11:02 peter 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.22 1998/05/02 15:51:54 peter Exp $";
|
||||
#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/socket.h>
|
||||
#include <sys/uio.h>
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/nameser.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include "res_config.h"
|
||||
#include <arpa/nameser.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <netdb.h>
|
||||
#include <errno.h>
|
||||
#include <netdb.h>
|
||||
#include <resolv.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <poll.h>
|
||||
|
||||
#include "res_config.h"
|
||||
|
||||
static int use_poll = 1; /* adapt to poll() syscall availability */
|
||||
/* 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 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
|
||||
|
||||
@ -137,9 +156,6 @@ static int vc = 0; /* is the socket a virtual ciruit? */
|
||||
}
|
||||
#endif
|
||||
|
||||
static res_send_qhook Qhook = NULL;
|
||||
static res_send_rhook Rhook = NULL;
|
||||
|
||||
void
|
||||
res_send_setqhook(hook)
|
||||
res_send_qhook hook;
|
||||
@ -170,12 +186,12 @@ res_isourserver(inp)
|
||||
const struct sockaddr_in *inp;
|
||||
{
|
||||
struct sockaddr_in ina;
|
||||
register int ns, ret;
|
||||
int ns, ret;
|
||||
|
||||
ina = *inp;
|
||||
ret = 0;
|
||||
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 &&
|
||||
srv->sin_port == ina.sin_port &&
|
||||
@ -192,7 +208,7 @@ res_isourserver(inp)
|
||||
* res_nameinquery(name, type, class, buf, eom)
|
||||
* look for (name,type,class) in the query section of packet (buf,eom)
|
||||
* requires:
|
||||
* buf + HFIXESDZ <= eom
|
||||
* buf + HFIXEDSZ <= eom
|
||||
* returns:
|
||||
* -1 : format error
|
||||
* 0 : not found
|
||||
@ -203,15 +219,15 @@ res_isourserver(inp)
|
||||
int
|
||||
res_nameinquery(name, type, class, buf, eom)
|
||||
const char *name;
|
||||
register int type, class;
|
||||
int type, class;
|
||||
const u_char *buf, *eom;
|
||||
{
|
||||
register const u_char *cp = buf + HFIXEDSZ;
|
||||
const u_char *cp = buf + HFIXEDSZ;
|
||||
int qdcount = ntohs(((HEADER*)buf)->qdcount);
|
||||
|
||||
while (qdcount-- > 0) {
|
||||
char tname[MAXDNAME+1];
|
||||
register int n, ttype, tclass;
|
||||
int n, ttype, tclass;
|
||||
|
||||
n = dn_expand(buf, eom, cp, tname, sizeof tname);
|
||||
if (n < 0)
|
||||
@ -219,8 +235,8 @@ res_nameinquery(name, type, class, buf, eom)
|
||||
cp += n;
|
||||
if (cp + 2 * INT16SZ > eom)
|
||||
return (-1);
|
||||
ttype = _getshort(cp); cp += INT16SZ;
|
||||
tclass = _getshort(cp); cp += INT16SZ;
|
||||
ttype = ns_get16(cp); cp += INT16SZ;
|
||||
tclass = ns_get16(cp); cp += INT16SZ;
|
||||
if (ttype == type &&
|
||||
tclass == class &&
|
||||
strcasecmp(tname, name) == 0)
|
||||
@ -245,17 +261,25 @@ res_queriesmatch(buf1, eom1, buf2, eom2)
|
||||
const u_char *buf1, *eom1;
|
||||
const u_char *buf2, *eom2;
|
||||
{
|
||||
register const u_char *cp = buf1 + HFIXEDSZ;
|
||||
const u_char *cp = buf1 + HFIXEDSZ;
|
||||
int qdcount = ntohs(((HEADER*)buf1)->qdcount);
|
||||
|
||||
if (buf1 + HFIXEDSZ > eom1 || buf2 + HFIXEDSZ > eom2)
|
||||
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))
|
||||
return (0);
|
||||
while (qdcount-- > 0) {
|
||||
char tname[MAXDNAME+1];
|
||||
register int n, ttype, tclass;
|
||||
int n, ttype, tclass;
|
||||
|
||||
n = dn_expand(buf1, eom1, cp, tname, sizeof tname);
|
||||
if (n < 0)
|
||||
@ -263,8 +287,8 @@ res_queriesmatch(buf1, eom1, buf2, eom2)
|
||||
cp += n;
|
||||
if (cp + 2 * INT16SZ > eom1)
|
||||
return (-1);
|
||||
ttype = _getshort(cp); cp += INT16SZ;
|
||||
tclass = _getshort(cp); cp += INT16SZ;
|
||||
ttype = ns_get16(cp); cp += INT16SZ;
|
||||
tclass = ns_get16(cp); cp += INT16SZ;
|
||||
if (!res_nameinquery(tname, ttype, tclass, buf2, eom2))
|
||||
return (0);
|
||||
}
|
||||
@ -280,9 +304,8 @@ res_send(buf, buflen, ans, anssiz)
|
||||
{
|
||||
HEADER *hp = (HEADER *) buf;
|
||||
HEADER *anhp = (HEADER *) ans;
|
||||
int gotsomewhere, connreset, terrno, try, v_circuit, resplen, ns;
|
||||
register int n;
|
||||
u_int badns; /* XXX NSMAX can't exceed #/bits in this var */
|
||||
int gotsomewhere, connreset, terrno, try, v_circuit, resplen, ns, n;
|
||||
u_int badns; /* XXX NSMAX can't exceed #/bits in this variable */
|
||||
|
||||
if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
|
||||
/* errno should have been set by res_init() in this case. */
|
||||
@ -358,7 +381,7 @@ res_send(buf, buflen, ans, anssiz)
|
||||
*/
|
||||
try = _res.retry;
|
||||
truncated = 0;
|
||||
if ((s < 0) || (!vc)) {
|
||||
if (s < 0 || !vc || hp->opcode == ns_o_update) {
|
||||
if (s >= 0)
|
||||
res_close();
|
||||
|
||||
@ -370,7 +393,7 @@ res_send(buf, buflen, ans, anssiz)
|
||||
}
|
||||
errno = 0;
|
||||
if (connect(s, (struct sockaddr *)nsap,
|
||||
sizeof(struct sockaddr)) < 0) {
|
||||
sizeof *nsap) < 0) {
|
||||
terrno = errno;
|
||||
Aerror(stderr, "connect/vc",
|
||||
errno, *nsap);
|
||||
@ -427,7 +450,7 @@ res_send(buf, buflen, ans, anssiz)
|
||||
res_close();
|
||||
goto next_ns;
|
||||
}
|
||||
resplen = _getshort(ans);
|
||||
resplen = ns_get16(ans);
|
||||
if (resplen > anssiz) {
|
||||
Dprint(_res.options & RES_DEBUG,
|
||||
(stdout, ";; response truncated\n")
|
||||
@ -509,7 +532,7 @@ res_send(buf, buflen, ans, anssiz)
|
||||
res_close();
|
||||
s = socket(PF_INET, SOCK_DGRAM, 0);
|
||||
if (s < 0) {
|
||||
#if !CAN_RECONNECT
|
||||
#ifndef CAN_RECONNECT
|
||||
bad_dg_sock:
|
||||
#endif
|
||||
terrno = errno;
|
||||
@ -518,6 +541,7 @@ res_send(buf, buflen, ans, anssiz)
|
||||
}
|
||||
connected = 0;
|
||||
}
|
||||
#ifndef CANNOT_CONNECT_DGRAM
|
||||
/*
|
||||
* On a 4.3BSD+ machine (client and server,
|
||||
* actually), sending to a nameserver datagram
|
||||
@ -540,7 +564,7 @@ res_send(buf, buflen, ans, anssiz)
|
||||
*/
|
||||
if (!connected) {
|
||||
if (connect(s, (struct sockaddr *)nsap,
|
||||
sizeof(struct sockaddr)
|
||||
sizeof *nsap
|
||||
) < 0) {
|
||||
Aerror(stderr,
|
||||
"connect(dg)",
|
||||
@ -563,7 +587,7 @@ res_send(buf, buflen, ans, anssiz)
|
||||
* for responses from more than one server.
|
||||
*/
|
||||
if (connected) {
|
||||
#if CAN_RECONNECT
|
||||
#ifdef CAN_RECONNECT
|
||||
struct sockaddr_in no_addr;
|
||||
|
||||
no_addr.sin_family = AF_INET;
|
||||
@ -572,7 +596,7 @@ res_send(buf, buflen, ans, anssiz)
|
||||
(void) connect(s,
|
||||
(struct sockaddr *)
|
||||
&no_addr,
|
||||
sizeof(no_addr));
|
||||
sizeof no_addr);
|
||||
#else
|
||||
int s1 = socket(PF_INET, SOCK_DGRAM,0);
|
||||
if (s1 < 0)
|
||||
@ -581,20 +605,23 @@ res_send(buf, buflen, ans, anssiz)
|
||||
(void) close(s1);
|
||||
Dprint(_res.options & RES_DEBUG,
|
||||
(stdout, ";; new DG socket\n"))
|
||||
#endif
|
||||
#endif /* CAN_RECONNECT */
|
||||
connected = 0;
|
||||
errno = 0;
|
||||
}
|
||||
#endif /* !CANNOT_CONNECT_DGRAM */
|
||||
if (sendto(s, (char*)buf, buflen, 0,
|
||||
(struct sockaddr *)nsap,
|
||||
sizeof(struct sockaddr))
|
||||
sizeof *nsap)
|
||||
!= buflen) {
|
||||
Aerror(stderr, "sendto", errno, *nsap);
|
||||
badns |= (1 << ns);
|
||||
res_close();
|
||||
goto next_ns;
|
||||
}
|
||||
#ifndef CANNOT_CONNECT_DGRAM
|
||||
}
|
||||
#endif /* !CANNOT_CONNECT_DGRAM */
|
||||
|
||||
/*
|
||||
* Wait for reply
|
||||
@ -723,7 +750,7 @@ res_send(buf, buflen, ans, anssiz)
|
||||
ans, (resplen>anssiz)?anssiz:resplen);
|
||||
goto wait;
|
||||
}
|
||||
#if CHECK_SRVR_ADDR
|
||||
#ifdef CHECK_SRVR_ADDR
|
||||
if (!(_res.options & RES_INSECURE1) &&
|
||||
!res_isourserver(&from)) {
|
||||
/*
|
||||
@ -830,12 +857,12 @@ res_send(buf, buflen, ans, anssiz)
|
||||
} /*foreach ns*/
|
||||
} /*foreach retry*/
|
||||
res_close();
|
||||
if (!v_circuit)
|
||||
if (!v_circuit) {
|
||||
if (!gotsomewhere)
|
||||
errno = ECONNREFUSED; /* no nameservers found */
|
||||
else
|
||||
errno = ETIMEDOUT; /* no answer obtained */
|
||||
else
|
||||
} else
|
||||
errno = terrno;
|
||||
return (-1);
|
||||
}
|
||||
|
@ -23,7 +23,7 @@
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* 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/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_ntos, sym_ntos);
|
||||
__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_comp, dn_comp);
|
||||
__weak_reference(__res_close, _res_close);
|
||||
#ifdef BIND_RES_POSIX3
|
||||
__weak_reference(__dn_expand, dn_expand);
|
||||
__weak_reference(__res_init, res_init);
|
||||
__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_mkquery, res_mkquery);
|
||||
__weak_reference(__res_send, res_send);
|
||||
#else
|
||||
__weak_reference(res_send, __res_send);
|
||||
#endif
|
||||
|
516
lib/libc/net/res_update.c
Normal file
516
lib/libc/net/res_update.c
Normal 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);
|
||||
}
|
Loading…
Reference in New Issue
Block a user