summaryrefslogtreecommitdiffstats
path: root/lib/libc/net
diff options
context:
space:
mode:
authorpeter <peter@FreeBSD.org>1998-06-11 09:03:02 +0000
committerpeter <peter@FreeBSD.org>1998-06-11 09:03:02 +0000
commit9492d9f3a276bb1ce288f7f1242f55ba381fb5d8 (patch)
tree1fedca6b8adcc385c524308ec3d4040f66de30c6 /lib/libc/net
parenta17a83618dae26baf5445f202b4ed0ce247b3f86 (diff)
downloadFreeBSD-src-9492d9f3a276bb1ce288f7f1242f55ba381fb5d8.zip
FreeBSD-src-9492d9f3a276bb1ce288f7f1242f55ba381fb5d8.tar.gz
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
Diffstat (limited to 'lib/libc/net')
-rw-r--r--lib/libc/net/Makefile.inc9
-rw-r--r--lib/libc/net/base64.c37
-rw-r--r--lib/libc/net/herror.c29
-rw-r--r--lib/libc/net/inet_net_pton.c7
-rw-r--r--lib/libc/net/inet_network.c5
-rw-r--r--lib/libc/net/inet_ntoa.c20
-rw-r--r--lib/libc/net/inet_ntop.c15
-rw-r--r--lib/libc/net/inet_pton.c22
-rw-r--r--lib/libc/net/ns_name.c593
-rw-r--r--lib/libc/net/ns_netint.c54
-rw-r--r--lib/libc/net/ns_parse.c190
-rw-r--r--lib/libc/net/ns_print.c743
-rw-r--r--lib/libc/net/ns_ttl.c151
-rw-r--r--lib/libc/net/nsap_addr.c12
-rw-r--r--lib/libc/net/res_comp.c748
-rw-r--r--lib/libc/net/res_config.h2
-rw-r--r--lib/libc/net/res_data.c94
-rw-r--r--lib/libc/net/res_debug.c1010
-rw-r--r--lib/libc/net/res_init.c45
-rw-r--r--lib/libc/net/res_mkquery.c39
-rw-r--r--lib/libc/net/res_mkupdate.c414
-rw-r--r--lib/libc/net/res_query.c61
-rw-r--r--lib/libc/net/res_send.c115
-rw-r--r--lib/libc/net/res_stubs.c21
-rw-r--r--lib/libc/net/res_update.c516
25 files changed, 3219 insertions, 1733 deletions
diff --git a/lib/libc/net/Makefile.inc b/lib/libc/net/Makefile.inc
index d01fd2e..18dca25 100644
--- a/lib/libc/net/Makefile.inc
+++ b/lib/libc/net/Makefile.inc
@@ -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
diff --git a/lib/libc/net/base64.c b/lib/libc/net/base64.c
index 868826a..3f2ed6c 100644
--- a/lib/libc/net/base64.c
+++ b/lib/libc/net/base64.c
@@ -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);
diff --git a/lib/libc/net/herror.c b/lib/libc/net/herror.c
index f22f519..ac3ca3b 100644
--- a/lib/libc/net/herror.c
+++ b/lib/libc/net/herror.c
@@ -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 --
diff --git a/lib/libc/net/inet_net_pton.c b/lib/libc/net/inet_net_pton.c
index 6fd6a06..6718329 100644
--- a/lib/libc/net/inet_net_pton.c
+++ b/lib/libc/net/inet_net_pton.c
@@ -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)
diff --git a/lib/libc/net/inet_network.c b/lib/libc/net/inet_network.c
index 6da2e8b..a62efc7 100644
--- a/lib/libc/net/inet_network.c
+++ b/lib/libc/net/inet_network.c
@@ -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 @@ again:
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++;
diff --git a/lib/libc/net/inet_ntoa.c b/lib/libc/net/inet_ntoa.c
index a37b1db..4fdceee 100644
--- a/lib/libc/net/inet_ntoa.c
+++ b/lib/libc/net/inet_ntoa.c
@@ -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 *)&in;
-#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);
}
diff --git a/lib/libc/net/inet_ntop.c b/lib/libc/net/inet_ntop.c
index 36dcb32..c44a973 100644
--- a/lib/libc/net/inet_ntop.c
+++ b/lib/libc/net/inet_ntop.c
@@ -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';
diff --git a/lib/libc/net/inet_pton.c b/lib/libc/net/inet_pton.c
index 054ff7d..19f28fb 100644
--- a/lib/libc/net/inet_pton.c
+++ b/lib/libc/net/inet_pton.c
@@ -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);
}
diff --git a/lib/libc/net/ns_name.c b/lib/libc/net/ns_name.c
new file mode 100644
index 0000000..bd4de80
--- /dev/null
+++ b/lib/libc/net/ns_name.c
@@ -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);
+}
diff --git a/lib/libc/net/ns_netint.c b/lib/libc/net/ns_netint.c
new file mode 100644
index 0000000..0dc8fe4
--- /dev/null
+++ b/lib/libc/net/ns_netint.c
@@ -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);
+}
diff --git a/lib/libc/net/ns_parse.c b/lib/libc/net/ns_parse.c
new file mode 100644
index 0000000..318b363
--- /dev/null
+++ b/lib/libc/net/ns_parse.c
@@ -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);
+}
diff --git a/lib/libc/net/ns_print.c b/lib/libc/net/ns_print.c
new file mode 100644
index 0000000..60b9017
--- /dev/null
+++ b/lib/libc/net/ns_print.c
@@ -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);
+}
diff --git a/lib/libc/net/ns_ttl.c b/lib/libc/net/ns_ttl.c
new file mode 100644
index 0000000..e62ae99
--- /dev/null
+++ b/lib/libc/net/ns_ttl.c
@@ -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);
+}
diff --git a/lib/libc/net/nsap_addr.c b/lib/libc/net/nsap_addr.c
index b0c6433..1db7dd7 100644
--- a/lib/libc/net/nsap_addr.c
+++ b/lib/libc/net/nsap_addr.c
@@ -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);
diff --git a/lib/libc/net/res_comp.c b/lib/libc/net/res_comp.c
index 8cd7469..de14f07 100644
--- a/lib/libc/net/res_comp.c
+++ b/lib/libc/net/res_comp.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.
- */
-
-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.
+ * 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.
*/
-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*/
diff --git a/lib/libc/net/res_config.h b/lib/libc/net/res_config.h
index f29246a..644e7d7 100644
--- a/lib/libc/net/res_config.h
+++ b/lib/libc/net/res_config.h
@@ -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 */
diff --git a/lib/libc/net/res_data.c b/lib/libc/net/res_data.c
index df0e0dd..b79e3ab 100644
--- a/lib/libc/net/res_data.c
+++ b/lib/libc/net/res_data.c
@@ -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
diff --git a/lib/libc/net/res_debug.c b/lib/libc/net/res_debug.c
index 06b8b42..d2e94cc 100644
--- a/lib/libc/net/res_debug.c
+++ b/lib/libc/net/res_debug.c
@@ -1,7 +1,5 @@
/*
- * ++Copyright++ 1985, 1990, 1993
- * -
- * Copyright (c) 1985, 1990, 1993
+ * Copyright (c) 1985
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -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,7 +49,9 @@
* 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.
- * -
+ */
+
+/*
* Portions Copyright (c) 1995 by International Business Machines, Inc.
*
* International Business Machines, Inc. (hereinafter called IBM) grants
@@ -72,184 +74,127 @@
* DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE, EVEN
* IF IBM IS APPRISED OF THE POSSIBILITY OF SUCH DAMAGES.
- * --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_debug.c 8.1 (Berkeley) 6/4/93";
-static char orig_rcsid[] = "From: Id: res_debug.c,v 8.20 1997/06/01 20:34:37 vixie Exp";
-static char rcsid[] = "$Id: res_debug.c,v 1.13 1997/02/22 15:00:31 peter Exp $";
+static char rcsid[] = "$Id: res_debug.c,v 8.20 1998/02/13 01:11:34 halley Exp $";
#endif /* LIBC_SCCS and not lint */
-#include "res_config.h"
-
-#include <sys/param.h>
#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 <errno.h>
+#include <math.h>
#include <netdb.h>
#include <resolv.h>
#include <stdio.h>
-#include <time.h>
-
#include <stdlib.h>
#include <string.h>
+#include <time.h>
+
+#define SPRINTF(x) sprintf x
extern const char *_res_opcodes[];
extern const char *_res_resultcodes[];
+extern const char *_res_sectioncodes[];
-/* XXX: we should use getservbyport() instead. */
-static const char *
-dewks(wks)
- int wks;
-{
- static char nbuf[20];
-
- switch (wks) {
- case 5: return "rje";
- case 7: return "echo";
- case 9: return "discard";
- case 11: return "systat";
- case 13: return "daytime";
- case 15: return "netstat";
- case 17: return "qotd";
- case 19: return "chargen";
- case 20: return "ftp-data";
- case 21: return "ftp";
- case 23: return "telnet";
- case 25: return "smtp";
- case 37: return "time";
- case 39: return "rlp";
- case 42: return "name";
- case 43: return "whois";
- case 53: return "domain";
- case 57: return "apts";
- case 59: return "apfs";
- case 67: return "bootps";
- case 68: return "bootpc";
- case 69: return "tftp";
- case 77: return "rje";
- case 79: return "finger";
- case 87: return "link";
- case 95: return "supdup";
- case 100: return "newacct";
- case 101: return "hostnames";
- case 102: return "iso-tsap";
- case 103: return "x400";
- case 104: return "x400-snd";
- case 105: return "csnet-ns";
- case 109: return "pop-2";
- case 111: return "sunrpc";
- case 113: return "auth";
- case 115: return "sftp";
- case 117: return "uucp-path";
- case 119: return "nntp";
- case 121: return "erpc";
- case 123: return "ntp";
- case 133: return "statsrv";
- case 136: return "profile";
- case 144: return "NeWS";
- case 161: return "snmp";
- case 162: return "snmp-trap";
- case 170: return "print-srv";
- default: (void) sprintf(nbuf, "%d", wks); return (nbuf);
- }
-}
+/*
+ * Print the current options.
+ */
+void
+fp_resstat(struct __res_state *statp, FILE *file) {
+ u_long mask;
-/* XXX: we should use getprotobynumber() instead. */
-static const char *
-deproto(protonum)
- int protonum;
-{
- static char nbuf[20];
-
- switch (protonum) {
- case 1: return "icmp";
- case 2: return "igmp";
- case 3: return "ggp";
- case 5: return "st";
- case 6: return "tcp";
- case 7: return "ucl";
- case 8: return "egp";
- case 9: return "igp";
- case 11: return "nvp-II";
- case 12: return "pup";
- case 16: return "chaos";
- case 17: return "udp";
- default: (void) sprintf(nbuf, "%d", protonum); return (nbuf);
- }
+ fprintf(file, ";; res options:");
+ if (!statp)
+ statp = &_res;
+ for (mask = 1; mask != 0; mask <<= 1)
+ if (statp->options & mask)
+ fprintf(file, " %s", p_option(mask));
+ putc('\n', file);
}
-static const u_char *
-do_rrset(msg, len, cp, cnt, pflag, file, hs)
- int cnt, pflag, len;
- const u_char *cp, *msg;
- const char *hs;
- FILE *file;
-{
- int n;
- int sflag;
+static void
+do_section(ns_msg *handle, ns_sect section, int pflag, FILE *file) {
+ int n, sflag, rrnum;
+ char buf[2048]; /* XXX need to malloc */
+ ns_opcode opcode;
+ ns_rr rr;
/*
* Print answer records.
*/
sflag = (_res.pfcode & pflag);
- if ((n = ntohs(cnt)) != 0) {
- if ((!_res.pfcode) ||
- ((sflag) && (_res.pfcode & RES_PRF_HEAD1)))
- fprintf(file, hs);
- while (--n >= 0) {
- if ((!_res.pfcode) || sflag) {
- cp = p_rr(cp, msg, file);
- } else {
- unsigned int dlen;
- cp += __dn_skipname(cp, cp + MAXCDNAME);
- cp += INT16SZ;
- cp += INT16SZ;
- cp += INT32SZ;
- dlen = _getshort((u_char*)cp);
- cp += INT16SZ;
- cp += dlen;
+ if (_res.pfcode && !sflag)
+ return;
+
+ opcode = ns_msg_getflag(*handle, ns_f_opcode);
+ rrnum = 0;
+ for (;;) {
+ if (ns_parserr(handle, section, rrnum, &rr)) {
+ if (errno != ENODEV)
+ fprintf(file, ";; ns_parserr: %s\n",
+ strerror(errno));
+ else if (rrnum > 0 && sflag != 0 &&
+ (_res.pfcode & RES_PRF_HEAD1))
+ putc('\n', file);
+ return;
+ }
+ if (rrnum == 0 && sflag != 0 && (_res.pfcode & RES_PRF_HEAD1))
+ fprintf(file, ";; %s SECTION:\n",
+ p_section(section, opcode));
+ if (section == ns_s_qd)
+ fprintf(file, ";;\t%s, type = %s, class = %s\n",
+ ns_rr_name(rr),
+ p_type(ns_rr_type(rr)),
+ p_class(ns_rr_class(rr)));
+ else {
+ n = ns_sprintrr(handle, &rr, NULL, NULL,
+ buf, sizeof buf);
+ if (n < 0) {
+ fprintf(file, ";; ns_sprintrr: %s\n",
+ strerror(errno));
+ return;
}
- if ((cp - msg) > len)
- return (NULL);
+ fputs(buf, file);
+ fputc('\n', file);
}
- if ((!_res.pfcode) ||
- ((sflag) && (_res.pfcode & RES_PRF_HEAD1)))
- putc('\n', file);
+ rrnum++;
}
- return (cp);
}
void
-__p_query(msg)
- const u_char *msg;
-{
- __fp_query(msg, stdout);
+p_query(const u_char *msg) {
+ fp_query(msg, stdout);
}
-/*
- * Print the current options.
- * This is intended to be primarily a debugging routine.
- */
void
-__fp_resstat(statp, file)
- struct __res_state *statp;
- FILE *file;
-{
- register u_long mask;
-
- fprintf(file, ";; res options:");
- if (!statp)
- statp = &_res;
- for (mask = 1; mask != 0; mask <<= 1)
- if (statp->options & mask)
- fprintf(file, " %s", p_option(mask));
- putc('\n', file);
+fp_query(const u_char *msg, FILE *file) {
+ fp_nquery(msg, PACKETSZ, file);
}
/*
@@ -257,147 +202,82 @@ __fp_resstat(statp, file)
* This is intended to be primarily a debugging routine.
*/
void
-__fp_nquery(msg, len, file)
- const u_char *msg;
- int len;
- FILE *file;
-{
- register const u_char *cp, *endMark;
- register const HEADER *hp;
- register int n;
+fp_nquery(const u_char *msg, int len, FILE *file) {
+ ns_msg handle;
+ int n, qdcount, ancount, nscount, arcount;
+ u_int opcode, rcode, id;
if ((_res.options & RES_INIT) == 0 && res_init() == -1)
return;
-#define TruncTest(x) if (x > endMark) goto trunc
-#define ErrorTest(x) if (x == NULL) goto error
+ if (ns_initparse(msg, len, &handle) < 0) {
+ fprintf(file, ";; ns_initparse: %s\n", strerror(errno));
+ return;
+ }
+ opcode = ns_msg_getflag(handle, ns_f_opcode);
+ rcode = ns_msg_getflag(handle, ns_f_rcode);
+ id = ns_msg_id(handle);
+ qdcount = ns_msg_count(handle, ns_s_qd);
+ ancount = ns_msg_count(handle, ns_s_an);
+ nscount = ns_msg_count(handle, ns_s_ns);
+ arcount = ns_msg_count(handle, ns_s_ar);
/*
* Print header fields.
*/
- hp = (HEADER *)msg;
- cp = msg + HFIXEDSZ;
- endMark = msg + len;
- if ((!_res.pfcode) || (_res.pfcode & RES_PRF_HEADX) || hp->rcode) {
- fprintf(file, ";; ->>HEADER<<- opcode: %s, status: %s, id: %d",
- _res_opcodes[hp->opcode],
- _res_resultcodes[hp->rcode],
- ntohs(hp->id));
- putc('\n', file);
- }
+ if ((!_res.pfcode) || (_res.pfcode & RES_PRF_HEADX) || rcode)
+ fprintf(file,
+ ";; ->>HEADER<<- opcode: %s, status: %s, id: %d\n",
+ _res_opcodes[opcode], _res_resultcodes[rcode], id);
if ((!_res.pfcode) || (_res.pfcode & RES_PRF_HEADX))
putc(';', file);
if ((!_res.pfcode) || (_res.pfcode & RES_PRF_HEAD2)) {
fprintf(file, "; flags:");
- if (hp->qr)
+ if (ns_msg_getflag(handle, ns_f_qr))
fprintf(file, " qr");
- if (hp->aa)
+ if (ns_msg_getflag(handle, ns_f_aa))
fprintf(file, " aa");
- if (hp->tc)
+ if (ns_msg_getflag(handle, ns_f_tc))
fprintf(file, " tc");
- if (hp->rd)
+ if (ns_msg_getflag(handle, ns_f_rd))
fprintf(file, " rd");
- if (hp->ra)
+ if (ns_msg_getflag(handle, ns_f_ra))
fprintf(file, " ra");
- if (hp->unused)
- fprintf(file, " UNUSED-BIT-ON");
- if (hp->ad)
+ if (ns_msg_getflag(handle, ns_f_z))
+ fprintf(file, " ??");
+ if (ns_msg_getflag(handle, ns_f_ad))
fprintf(file, " ad");
- if (hp->cd)
+ if (ns_msg_getflag(handle, ns_f_cd))
fprintf(file, " cd");
}
if ((!_res.pfcode) || (_res.pfcode & RES_PRF_HEAD1)) {
- fprintf(file, "; Ques: %d", ntohs(hp->qdcount));
- fprintf(file, ", Ans: %d", ntohs(hp->ancount));
- fprintf(file, ", Auth: %d", ntohs(hp->nscount));
- fprintf(file, ", Addit: %d", ntohs(hp->arcount));
+ fprintf(file, "; %s: %d",
+ p_section(ns_s_qd, opcode), qdcount);
+ fprintf(file, ", %s: %d",
+ p_section(ns_s_an, opcode), ancount);
+ fprintf(file, ", %s: %d",
+ p_section(ns_s_ns, opcode), nscount);
+ fprintf(file, ", %s: %d",
+ p_section(ns_s_ar, opcode), arcount);
}
if ((!_res.pfcode) || (_res.pfcode &
(RES_PRF_HEADX | RES_PRF_HEAD2 | RES_PRF_HEAD1))) {
putc('\n',file);
}
/*
- * Print question records.
+ * Print the various sections.
*/
- if ((n = ntohs(hp->qdcount)) != 0) {
- if ((!_res.pfcode) || (_res.pfcode & RES_PRF_QUES))
- fprintf(file, ";; QUESTIONS:\n");
- while (--n >= 0) {
- if ((!_res.pfcode) || (_res.pfcode & RES_PRF_QUES))
- fprintf(file, ";;\t");
- TruncTest(cp);
- if ((!_res.pfcode) || (_res.pfcode & RES_PRF_QUES))
- cp = p_cdnname(cp, msg, len, file);
- else {
- int n;
- char name[MAXDNAME];
-
- if ((n = dn_expand(msg, msg+len, cp, name,
- sizeof name)) < 0)
- cp = NULL;
- else
- cp += n;
- }
- ErrorTest(cp);
- TruncTest(cp);
- if ((!_res.pfcode) || (_res.pfcode & RES_PRF_QUES))
- fprintf(file, ", type = %s",
- __p_type(_getshort((u_char*)cp)));
- cp += INT16SZ;
- TruncTest(cp);
- if ((!_res.pfcode) || (_res.pfcode & RES_PRF_QUES))
- fprintf(file, ", class = %s\n",
- __p_class(_getshort((u_char*)cp)));
- cp += INT16SZ;
- if ((!_res.pfcode) || (_res.pfcode & RES_PRF_QUES))
- putc('\n', file);
- }
- }
- /*
- * Print authoritative answer records
- */
- TruncTest(cp);
- cp = do_rrset(msg, len, cp, hp->ancount, RES_PRF_ANS, file,
- ";; ANSWERS:\n");
- ErrorTest(cp);
-
- /*
- * print name server records
- */
- TruncTest(cp);
- cp = do_rrset(msg, len, cp, hp->nscount, RES_PRF_AUTH, file,
- ";; AUTHORITY RECORDS:\n");
- ErrorTest(cp);
-
- TruncTest(cp);
- /*
- * print additional records
- */
- cp = do_rrset(msg, len, cp, hp->arcount, RES_PRF_ADD, file,
- ";; ADDITIONAL RECORDS:\n");
- ErrorTest(cp);
- return;
- trunc:
- fprintf(file, "\n;; ...truncated\n");
- return;
- error:
- fprintf(file, "\n;; ...malformed\n");
-}
-
-void
-__fp_query(msg, file)
- const u_char *msg;
- FILE *file;
-{
- fp_nquery(msg, PACKETSZ, file);
+ do_section(&handle, ns_s_qd, RES_PRF_QUES, file);
+ do_section(&handle, ns_s_an, RES_PRF_ANS, file);
+ do_section(&handle, ns_s_ns, RES_PRF_AUTH, file);
+ do_section(&handle, ns_s_ar, RES_PRF_ADD, file);
+ if (qdcount == 0 && ancount == 0 &&
+ nscount == 0 && arcount == 0)
+ putc('\n', file);
}
const u_char *
-__p_cdnname(cp, msg, len, file)
- const u_char *cp, *msg;
- int len;
- FILE *file;
-{
+p_cdnname(const u_char *cp, const u_char *msg, int len, FILE *file) {
char name[MAXDNAME];
int n;
@@ -411,19 +291,15 @@ __p_cdnname(cp, msg, len, file)
}
const u_char *
-__p_cdname(cp, msg, file)
- const u_char *cp, *msg;
- FILE *file;
-{
+p_cdname(const u_char *cp, const u_char *msg, FILE *file) {
return (p_cdnname(cp, msg, PACKETSZ, file));
}
-
/* Return a fully-qualified domain name from a compressed name (with
length supplied). */
const u_char *
-__p_fqnname(cp, msg, msglen, name, namelen)
+p_fqnname(cp, msg, msglen, name, namelen)
const u_char *cp, *msg;
int msglen;
char *name;
@@ -433,27 +309,24 @@ __p_fqnname(cp, msg, msglen, name, namelen)
if ((n = dn_expand(msg, cp + msglen, cp, name, namelen)) < 0)
return (NULL);
- newlen = strlen (name);
- if (newlen == 0 || name[newlen - 1] != '.')
- if (newlen+1 >= namelen) /* Lack space for final dot */
+ newlen = strlen(name);
+ if (newlen == 0 || name[newlen - 1] != '.') {
+ if (newlen + 1 >= namelen) /* Lack space for final dot */
return (NULL);
else
strcpy(name + newlen, ".");
+ }
return (cp + n);
}
-/* XXX: the rest of these functions need to become length-limited, too. (vix)
- */
+/* XXX: the rest of these functions need to become length-limited, too. */
const u_char *
-__p_fqname(cp, msg, file)
- const u_char *cp, *msg;
- FILE *file;
-{
+p_fqname(const u_char *cp, const u_char *msg, FILE *file) {
char name[MAXDNAME];
const u_char *n;
- n = __p_fqnname(cp, msg, MAXCDNAME, name, sizeof name);
+ n = p_fqnname(cp, msg, MAXCDNAME, name, sizeof name);
if (n == NULL)
return (NULL);
fputs(name, file);
@@ -461,397 +334,6 @@ __p_fqname(cp, msg, file)
}
/*
- * Print resource record fields in human readable form.
- */
-const u_char *
-__p_rr(cp, msg, file)
- const u_char *cp, *msg;
- FILE *file;
-{
- int type, class, dlen, n, c;
- struct in_addr inaddr;
- const u_char *cp1, *cp2;
- u_int32_t tmpttl, t;
- int lcnt;
- u_int16_t keyflags;
- char rrname[MAXDNAME]; /* The fqdn of this RR */
- char base64_key[MAX_KEY_BASE64];
-
- if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
- h_errno = NETDB_INTERNAL;
- return (NULL);
- }
- cp = __p_fqnname(cp, msg, MAXCDNAME, rrname, sizeof rrname);
- if (!cp)
- return (NULL); /* compression error */
- fputs(rrname, file);
-
- type = _getshort((u_char*)cp);
- cp += INT16SZ;
- class = _getshort((u_char*)cp);
- cp += INT16SZ;
- tmpttl = _getlong((u_char*)cp);
- cp += INT32SZ;
- dlen = _getshort((u_char*)cp);
- cp += INT16SZ;
- cp1 = cp;
- if ((!_res.pfcode) || (_res.pfcode & RES_PRF_TTLID))
- fprintf(file, "\t%lu", (u_long)tmpttl);
- if ((!_res.pfcode) || (_res.pfcode & RES_PRF_CLASS))
- fprintf(file, "\t%s", __p_class(class));
- fprintf(file, "\t%s", __p_type(type));
- /*
- * Print type specific data, if appropriate
- */
- switch (type) {
- case T_A:
- switch (class) {
- case C_IN:
- case C_HS:
- bcopy(cp, (char *)&inaddr, INADDRSZ);
- if (dlen == 4) {
- fprintf(file, "\t%s", inet_ntoa(inaddr));
- cp += dlen;
- } else if (dlen == 7) {
- char *address;
- u_char protocol;
- u_short port;
-
- address = inet_ntoa(inaddr);
- cp += INADDRSZ;
- protocol = *(u_char*)cp;
- cp += sizeof (u_char);
- port = _getshort((u_char*)cp);
- cp += INT16SZ;
- fprintf(file, "\t%s\t; proto %d, port %d",
- address, protocol, port);
- }
- break;
- default:
- cp += dlen;
- }
- break;
- case T_CNAME:
- case T_MB:
- case T_MG:
- case T_MR:
- case T_NS:
- case T_PTR:
- putc('\t', file);
- if ((cp = p_fqname(cp, msg, file)) == NULL)
- return (NULL);
- break;
-
- case T_HINFO:
- case T_ISDN:
- cp2 = cp + dlen;
- (void) fputs("\t\"", file);
- if ((n = (unsigned char) *cp++) != 0) {
- for (c = n; c > 0 && cp < cp2; c--) {
- if (strchr("\n\"\\", *cp))
- (void) putc('\\', file);
- (void) putc(*cp++, file);
- }
- }
- putc('"', file);
- if (cp < cp2 && (n = (unsigned char) *cp++) != 0) {
- (void) fputs ("\t\"", file);
- for (c = n; c > 0 && cp < cp2; c--) {
- if (strchr("\n\"\\", *cp))
- (void) putc('\\', file);
- (void) putc(*cp++, file);
- }
- putc('"', file);
- } else if (type == T_HINFO) {
- (void) fputs("\"?\"", file);
- fprintf(file, "\n;; *** Warning *** OS-type missing");
- }
- break;
-
- case T_SOA:
- putc('\t', file);
- if ((cp = p_fqname(cp, msg, file)) == NULL)
- return (NULL);
- putc(' ', file);
- if ((cp = p_fqname(cp, msg, file)) == NULL)
- return (NULL);
- fputs(" (\n", file);
- t = _getlong((u_char*)cp); cp += INT32SZ;
- fprintf(file, "\t\t\t%lu\t; serial\n", (u_long)t);
- t = _getlong((u_char*)cp); cp += INT32SZ;
- fprintf(file, "\t\t\t%lu\t; refresh (%s)\n",
- (u_long)t, __p_time(t));
- t = _getlong((u_char*)cp); cp += INT32SZ;
- fprintf(file, "\t\t\t%lu\t; retry (%s)\n",
- (u_long)t, __p_time(t));
- t = _getlong((u_char*)cp); cp += INT32SZ;
- fprintf(file, "\t\t\t%lu\t; expire (%s)\n",
- (u_long)t, __p_time(t));
- t = _getlong((u_char*)cp); cp += INT32SZ;
- fprintf(file, "\t\t\t%lu )\t; minimum (%s)",
- (u_long)t, __p_time(t));
- break;
-
- case T_MX:
- case T_AFSDB:
- case T_RT:
- fprintf(file, "\t%d ", _getshort((u_char*)cp));
- cp += INT16SZ;
- if ((cp = p_fqname(cp, msg, file)) == NULL)
- return (NULL);
- break;
-
- case T_PX:
- fprintf(file, "\t%d ", _getshort((u_char*)cp));
- cp += INT16SZ;
- if ((cp = p_fqname(cp, msg, file)) == NULL)
- return (NULL);
- putc(' ', file);
- if ((cp = p_fqname(cp, msg, file)) == NULL)
- return (NULL);
- break;
-
- case T_X25:
- cp2 = cp + dlen;
- (void) fputs("\t\"", file);
- if ((n = (unsigned char) *cp++) != 0) {
- for (c = n; c > 0 && cp < cp2; c--) {
- if (strchr("\n\"\\", *cp))
- (void) putc('\\', file);
- (void) putc(*cp++, file);
- }
- }
- putc('"', file);
- break;
-
- case T_TXT:
- (void) putc('\t', file);
- cp2 = cp1 + dlen;
- while (cp < cp2) {
- putc('"', file);
- if ((n = (unsigned char) *cp++) != '\0') {
- for (c = n; c > 0 && cp < cp2; c--) {
- if (strchr("\n\"\\", *cp))
- (void) putc('\\', file);
- (void) putc(*cp++, file);
- }
- }
- putc('"', file);
- if (cp < cp2)
- putc(' ', file);
- }
- break;
-
- case T_NSAP:
- (void) fprintf(file, "\t%s", inet_nsap_ntoa(dlen, cp, NULL));
- cp += dlen;
- break;
-
- case T_AAAA: {
- char t[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"];
-
- fprintf(file, "\t%s", inet_ntop(AF_INET6, cp, t, sizeof t));
- cp += dlen;
- break;
- }
-
- case T_LOC: {
- char t[255];
-
- fprintf(file, "\t%s", loc_ntoa(cp, t));
- cp += dlen;
- break;
- }
-
- case T_NAPTR: {
- u_int order, preference;
-
- order = _getshort(cp); cp += INT16SZ;
- preference = _getshort(cp); cp += INT16SZ;
- fprintf(file, "\t%u %u ",order, preference);
- /* Flags */
- n = *cp++;
- fprintf(file,"\"%.*s\" ", (int)n, cp);
- cp += n;
- /* Service */
- n = *cp++;
- fprintf(file,"\"%.*s\" ", (int)n, cp);
- cp += n;
- /* Regexp */
- n = *cp++;
- fprintf(file,"\"%.*s\" ", (int)n, cp);
- cp += n;
- if ((cp = p_fqname(cp, msg, file)) == NULL)
- return (NULL);
- break;
- }
-
- case T_SRV: {
- u_int priority, weight, port;
-
- priority = _getshort(cp); cp += INT16SZ;
- weight = _getshort(cp); cp += INT16SZ;
- port = _getshort(cp); cp += INT16SZ;
- fprintf(file, "\t%u %u %u ", priority, weight, port);
- if ((cp = p_fqname(cp, msg, file)) == NULL)
- return (NULL);
- break;
- }
-
- case T_MINFO:
- case T_RP:
- putc('\t', file);
- if ((cp = p_fqname(cp, msg, file)) == NULL)
- return (NULL);
- putc(' ', file);
- if ((cp = p_fqname(cp, msg, file)) == NULL)
- return (NULL);
- break;
-
- case T_UINFO:
- putc('\t', file);
- fputs((char *)cp, file);
- cp += dlen;
- break;
-
- case T_UID:
- case T_GID:
- if (dlen == 4) {
- fprintf(file, "\t%u", _getlong((u_char*)cp));
- cp += INT32SZ;
- }
- break;
-
- case T_WKS:
- if (dlen < INT32SZ + 1)
- break;
- bcopy(cp, (char *)&inaddr, INADDRSZ);
- cp += INT32SZ;
- fprintf(file, "\t%s %s ( ",
- inet_ntoa(inaddr),
- deproto((int) *cp));
- cp += sizeof (u_char);
- n = 0;
- lcnt = 0;
- while (cp < cp1 + dlen) {
- c = *cp++;
- do {
- if (c & 0200) {
- if (lcnt == 0) {
- fputs("\n\t\t\t", file);
- lcnt = 5;
- }
- fputs(dewks(n), file);
- putc(' ', file);
- lcnt--;
- }
- c <<= 1;
- } while (++n & 07);
- }
- putc(')', file);
- break;
-
- case T_KEY:
- putc('\t', file);
- keyflags = _getshort(cp);
- cp += 2;
- fprintf(file,"0x%04x", keyflags ); /* flags */
- fprintf(file," %u", *cp++); /* protocol */
- fprintf(file," %u (", *cp++); /* algorithm */
-
- n = b64_ntop(cp, (cp1 + dlen) - cp,
- base64_key, sizeof base64_key);
- for (c = 0; c < n; ++c) {
- if (0 == (c & 0x3F))
- fprintf(file, "\n\t");
- putc(base64_key[c], file); /* public key data */
- }
-
- fprintf(file, " )");
- if (n < 0)
- fprintf(file, "\t; BAD BASE64");
- fflush(file);
- cp = cp1 + dlen;
- break;
-
- case T_SIG:
- type = _getshort((u_char*)cp);
- cp += INT16SZ;
- fprintf(file, " %s", p_type(type));
- fprintf(file, "\t%d", *cp++); /* algorithm */
- /* Check label value and print error if wrong. */
- n = *cp++;
- c = dn_count_labels (rrname);
- if (n != c)
- fprintf(file, "\t; LABELS WRONG (%d should be %d)\n\t",
- n, c);
- /* orig ttl */
- n = _getlong((u_char*)cp);
- if (n != tmpttl)
- fprintf(file, " %u", n);
- cp += INT32SZ;
- /* sig expire */
- fprintf(file, " (\n\t%s",
- __p_secstodate(_getlong((u_char*)cp)));
- cp += INT32SZ;
- /* time signed */
- fprintf(file, " %s", __p_secstodate(_getlong((u_char*)cp)));
- cp += INT32SZ;
- /* sig footprint */
- fprintf(file," %u ", _getshort((u_char*)cp));
- cp += INT16SZ;
- /* signer's name */
- cp = p_fqname(cp, msg, file);
- n = b64_ntop(cp, (cp1 + dlen) - cp,
- base64_key, sizeof base64_key);
- for (c = 0; c < n; c++) {
- if (0 == (c & 0x3F))
- fprintf (file, "\n\t");
- putc(base64_key[c], file); /* signature */
- }
- /* Clean up... */
- fprintf(file, " )");
- if (n < 0)
- fprintf(file, "\t; BAD BASE64");
- fflush(file);
- cp = cp1+dlen;
- break;
-
-#ifdef ALLOW_T_UNSPEC
- case T_UNSPEC:
- {
- int NumBytes = 8;
- u_char *DataPtr;
- int i;
-
- if (dlen < NumBytes) NumBytes = dlen;
- fprintf(file, "\tFirst %d bytes of hex data:",
- NumBytes);
- for (i = 0, DataPtr = cp; i < NumBytes; i++, DataPtr++)
- fprintf(file, " %x", *DataPtr);
- cp += dlen;
- }
- break;
-#endif /* ALLOW_T_UNSPEC */
-
- default:
- fprintf(file, "\t?%d?", type);
- cp += dlen;
- }
-#if 0
- fprintf(file, "\t; dlen=%d, ttl %s\n", dlen, __p_time(tmpttl));
-#else
- putc('\n', file);
-#endif
- if (cp - cp1 != dlen) {
- fprintf(file, ";; packet size error (found %d, dlen was %d)\n",
- cp - cp1, dlen);
- cp = NULL;
- }
- return (cp);
-}
-
-/*
* Names of RR classes and qclasses. Classes and qclasses are the same, except
* that C_ANY is a qclass but not a class. (You can ask for records of class
* C_ANY, but you can't have any records of that class in the database.)
@@ -862,10 +344,30 @@ const struct res_sym __p_class_syms[] = {
{C_HS, "HS"},
{C_HS, "HESIOD"},
{C_ANY, "ANY"},
+ {C_NONE, "NONE"},
{C_IN, (char *)0}
};
/*
+ * Names of message sections.
+ */
+const struct res_sym __p_default_section_syms[] = {
+ {ns_s_qd, "QUERY"},
+ {ns_s_an, "ANSWER"},
+ {ns_s_ns, "AUTHORITY"},
+ {ns_s_ar, "ADDITIONAL"},
+ {0, (char *)0}
+};
+
+const struct res_sym __p_update_section_syms[] = {
+ {S_ZONE, "ZONE"},
+ {S_PREREQ, "PREREQUISITE"},
+ {S_UPDATE, "UPDATE"},
+ {S_ADDT, "ADDITIONAL"},
+ {0, (char *)0}
+};
+
+/*
* Names of RR types and qtypes. Types and qtypes are the same, except
* that T_ANY is a qtype but not a type. (You can ask for records of type
* T_ANY, but you can't have any records of that type in the database.)
@@ -909,24 +411,14 @@ const struct res_sym __p_type_syms[] = {
{T_AXFR, "AXFR", "zone transfer"},
{T_MAILB, "MAILB", "mailbox-related data (deprecated)"},
{T_MAILA, "MAILA", "mail agent (deprecated)"},
- {T_UINFO, "UINFO", "user information (nonstandard)"},
- {T_UID, "UID", "user ID (nonstandard)"},
- {T_GID, "GID", "group ID (nonstandard)"},
{T_NAPTR, "NAPTR", "URN Naming Authority"},
-#ifdef ALLOW_T_UNSPEC
- {T_UNSPEC, "UNSPEC", "unspecified data (nonstandard)"},
-#endif /* ALLOW_T_UNSPEC */
{T_ANY, "ANY", "\"any\""},
{0, NULL, NULL}
};
int
-__sym_ston(syms, name, success)
- const struct res_sym *syms;
- char *name;
- int *success;
-{
- for (NULL; syms->name != 0; syms++) {
+sym_ston(const struct res_sym *syms, const char *name, int *success) {
+ for ((void)NULL; syms->name != 0; syms++) {
if (strcasecmp (name, syms->name) == 0) {
if (success)
*success = 1;
@@ -939,14 +431,10 @@ __sym_ston(syms, name, success)
}
const char *
-__sym_ntos(syms, number, success)
- const struct res_sym *syms;
- int number;
- int *success;
-{
+sym_ntos(const struct res_sym *syms, int number, int *success) {
static char unname[20];
- for (NULL; syms->name != 0; syms++) {
+ for ((void)NULL; syms->name != 0; syms++) {
if (number == syms->number) {
if (success)
*success = 1;
@@ -954,22 +442,17 @@ __sym_ntos(syms, number, success)
}
}
- sprintf (unname, "%d", number);
+ sprintf(unname, "%d", number);
if (success)
*success = 0;
return (unname);
}
-
const char *
-__sym_ntop(syms, number, success)
- const struct res_sym *syms;
- int number;
- int *success;
-{
+sym_ntop(const struct res_sym *syms, int number, int *success) {
static char unname[20];
- for (NULL; syms->name != 0; syms++) {
+ for ((void)NULL; syms->name != 0; syms++) {
if (number == syms->number) {
if (success)
*success = 1;
@@ -983,32 +466,44 @@ __sym_ntop(syms, number, success)
}
/*
- * Return a string for the type
+ * Return a string for the type.
*/
const char *
-__p_type(type)
- int type;
-{
- return (__sym_ntos (__p_type_syms, type, (int *)0));
+p_type(int type) {
+ return (sym_ntos(__p_type_syms, type, (int *)0));
}
/*
- * Return a mnemonic for class
+ * Return a string for the type.
*/
const char *
-__p_class(class)
- int class;
-{
- return (__sym_ntos (__p_class_syms, class, (int *)0));
+p_section(int section, int opcode) {
+ const struct res_sym *symbols;
+
+ switch (opcode) {
+ case ns_o_update:
+ symbols = __p_update_section_syms;
+ break;
+ default:
+ symbols = __p_default_section_syms;
+ break;
+ }
+ return (sym_ntos(symbols, section, (int *)0));
+}
+
+/*
+ * Return a mnemonic for class.
+ */
+const char *
+p_class(int class) {
+ return (sym_ntos(__p_class_syms, class, (int *)0));
}
/*
* Return a mnemonic for an option
*/
const char *
-__p_option(option)
- u_long option;
-{
+p_option(u_long option) {
static char nbuf[40];
switch (option) {
@@ -1030,56 +525,18 @@ __p_option(option)
}
/*
- * Return a mnemonic for a time to live
+ * Return a mnemonic for a time to live.
*/
const char *
-p_time(value)
- u_int32_t value;
-{
+p_time(u_int32_t value) {
static char nbuf[40];
- int secs, mins, hours, days;
- register char *p;
-
- if (value == 0) {
- strcpy(nbuf, "0 secs");
- return (nbuf);
- }
- secs = value % 60;
- value /= 60;
- mins = value % 60;
- value /= 60;
- hours = value % 24;
- value /= 24;
- days = value;
- value = 0;
-
-#define PLURALIZE(x) x, (x == 1) ? "" : "s"
- p = nbuf;
- if (days) {
- (void)sprintf(p, "%d day%s", PLURALIZE(days));
- while (*++p);
- }
- if (hours) {
- if (days)
- *p++ = ' ';
- (void)sprintf(p, "%d hour%s", PLURALIZE(hours));
- while (*++p);
- }
- if (mins) {
- if (days || hours)
- *p++ = ' ';
- (void)sprintf(p, "%d min%s", PLURALIZE(mins));
- while (*++p);
- }
- if (secs || ! (days || hours || mins)) {
- if (days || hours || mins)
- *p++ = ' ';
- (void)sprintf(p, "%d sec%s", PLURALIZE(secs));
- }
+ if (ns_format_ttl(value, nbuf, sizeof nbuf) < 0)
+ sprintf(nbuf, "%u", value);
return (nbuf);
}
+
/*
* routines to convert between on-the-wire RR format and zone file format.
* Does not contain conversion to/from decimal degrees; divide or multiply
@@ -1112,47 +569,40 @@ static u_int8_t
precsize_aton(strptr)
char **strptr;
{
+ unsigned int mval = 0, cmval = 0;
u_int8_t retval = 0;
char *cp;
- int exponent = 0;
- int mantissa = 0;
+ int exponent;
+ int mantissa;
cp = *strptr;
- while (isdigit(*cp)) {
- if (mantissa == 0)
- mantissa = *cp - '0';
- else
- exponent++;
- cp++;
- }
- if (*cp == '.') {
+ while (isdigit(*cp))
+ mval = mval * 10 + (*cp++ - '0');
+
+ if (*cp == '.') { /* centimeters */
cp++;
if (isdigit(*cp)) {
- if (mantissa == 0)
- mantissa = *cp - '0';
- else
- exponent++;
- cp++;
-
+ cmval = (*cp++ - '0') * 10;
if (isdigit(*cp)) {
- if (mantissa == 0)
- mantissa = *cp - '0';
- else
- exponent++;
- cp++;
+ cmval += (*cp++ - '0');
}
- else
- exponent++;
}
}
- else
- exponent += 2;
+ cmval = (mval * 100) + cmval;
+
+ for (exponent = 0; exponent < 9; exponent++)
+ if (cmval < poweroften[exponent+1])
+ break;
+
+ mantissa = cmval / poweroften[exponent];
+ if (mantissa > 9)
+ mantissa = 9;
- if (mantissa == 0)
- exponent = 0;
retval = (mantissa << 4) | exponent;
+
*strptr = cp;
+
return (retval);
}
@@ -1162,7 +612,7 @@ latlon2ul(latlonstrptr,which)
char **latlonstrptr;
int *which;
{
- register char *cp;
+ char *cp;
u_int32_t retval;
int deg = 0, min = 0, secs = 0, secsfrac = 0;
@@ -1373,14 +823,14 @@ loc_ntoa(binary, ascii)
char *ascii;
{
static char *error = "?";
- register const u_char *cp = binary;
+ const u_char *cp = binary;
int latdeg, latmin, latsec, latsecfrac;
int longdeg, longmin, longsec, longsecfrac;
char northsouth, eastwest;
int altmeters, altfrac, altsign;
- const int referencealt = 100000 * 100;
+ const u_int32_t referencealt = 100000 * 100;
int32_t latval, longval, altval;
u_int32_t templ;
@@ -1391,7 +841,7 @@ loc_ntoa(binary, ascii)
versionval = *cp++;
if (versionval) {
- sprintf(ascii, "; error: unknown LOC RR version");
+ (void) sprintf(ascii, "; error: unknown LOC RR version");
return (ascii);
}
@@ -1472,14 +922,12 @@ loc_ntoa(binary, ascii)
/* Return the number of DNS hierarchy levels in the name. */
int
-__dn_count_labels(name)
- char *name;
-{
+dn_count_labels(const char *name) {
int i, len, count;
len = strlen(name);
-
- for(i = 0, count = 0; i < len; i++) {
+ for (i = 0, count = 0; i < len; i++) {
+ /* XXX need to check for \. or use named's nlabels(). */
if (name[i] == '.')
count++;
}
@@ -1503,9 +951,7 @@ __dn_count_labels(name)
* SIG records are required to be printed like this, by the Secure DNS RFC.
*/
char *
-__p_secstodate (secs)
- unsigned long secs;
-{
+p_secstodate (u_long secs) {
static char output[15]; /* YYYYMMDDHHMMSS and null */
time_t clock = secs;
struct tm *time;
diff --git a/lib/libc/net/res_init.c b/lib/libc/net/res_init.c
index bf12280..b9eddaa 100644
--- a/lib/libc/net/res_init.c
+++ b/lib/libc/net/res_init.c
@@ -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 */
}
diff --git a/lib/libc/net/res_mkquery.c b/lib/libc/net/res_mkquery.c
index cfc9d33..55c024e 100644
--- a/lib/libc/net/res_mkquery.c
+++ b/lib/libc/net/res_mkquery.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,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);
diff --git a/lib/libc/net/res_mkupdate.c b/lib/libc/net/res_mkupdate.c
new file mode 100644
index 0000000..a9dcc86
--- /dev/null
+++ b/lib/libc/net/res_mkupdate.c
@@ -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);
+}
diff --git a/lib/libc/net/res_query.c b/lib/libc/net/res_query.c
index 3716e63..4de8a0e 100644
--- a/lib/libc/net/res_query.c
+++ b/lib/libc/net/res_query.c
@@ -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)
diff --git a/lib/libc/net/res_send.c b/lib/libc/net/res_send.c
index a29f43a..45c9661 100644
--- a/lib/libc/net/res_send.c
+++ b/lib/libc/net/res_send.c
@@ -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/inet.h>
-#include "res_config.h"
+#include <netinet/in.h>
#include <arpa/nameser.h>
+#include <arpa/inet.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 @@ read_len:
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 @@ read_len:
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 @@ read_len:
}
connected = 0;
}
+#ifndef CANNOT_CONNECT_DGRAM
/*
* On a 4.3BSD+ machine (client and server,
* actually), sending to a nameserver datagram
@@ -540,7 +564,7 @@ read_len:
*/
if (!connected) {
if (connect(s, (struct sockaddr *)nsap,
- sizeof(struct sockaddr)
+ sizeof *nsap
) < 0) {
Aerror(stderr,
"connect(dg)",
@@ -563,7 +587,7 @@ read_len:
* 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 @@ read_len:
(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 @@ read_len:
(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 @@ read_len:
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 @@ read_len:
} /*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);
}
diff --git a/lib/libc/net/res_stubs.c b/lib/libc/net/res_stubs.c
index e156608..056bc6c 100644
--- a/lib/libc/net/res_stubs.c
+++ b/lib/libc/net/res_stubs.c
@@ -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
diff --git a/lib/libc/net/res_update.c b/lib/libc/net/res_update.c
new file mode 100644
index 0000000..c76d22e
--- /dev/null
+++ b/lib/libc/net/res_update.c
@@ -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);
+}
OpenPOWER on IntegriCloud