1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/other-licenses/android/ns_print.c Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,928 @@ 1.4 +/* $NetBSD: ns_print.c,v 1.5 2004/11/07 02:19:49 christos Exp $ */ 1.5 + 1.6 +/* 1.7 + * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC") 1.8 + * Copyright (c) 1996-1999 by Internet Software Consortium. 1.9 + * 1.10 + * Permission to use, copy, modify, and distribute this software for any 1.11 + * purpose with or without fee is hereby granted, provided that the above 1.12 + * copyright notice and this permission notice appear in all copies. 1.13 + * 1.14 + * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES 1.15 + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 1.16 + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR 1.17 + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 1.18 + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 1.19 + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT 1.20 + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 1.21 + */ 1.22 + 1.23 +/* 1.24 + * This version of this file is derived from Android 2.3 "Gingerbread", 1.25 + * which contains uncredited changes by Android/Google developers. It has 1.26 + * been modified in 2011 for use in the Android build of Mozilla Firefox by 1.27 + * Mozilla contributors (including Michael Edwards <m.k.edwards@gmail.com>, 1.28 + * and Steve Workman <sjhworkman@gmail.com>). 1.29 + * These changes are offered under the same license as the original NetBSD 1.30 + * file, whose copyright and license are unchanged above. 1.31 + */ 1.32 + 1.33 +#define ANDROID_CHANGES 1 1.34 +#define MOZILLA_NECKO_EXCLUDE_CODE 1 1.35 + 1.36 +#include <sys/cdefs.h> 1.37 +#ifndef lint 1.38 +#ifdef notdef 1.39 +static const char rcsid[] = "Id: ns_print.c,v 1.3.2.1.4.5 2004/07/28 20:16:45 marka Exp"; 1.40 +#else 1.41 +__RCSID("$NetBSD: ns_print.c,v 1.5 2004/11/07 02:19:49 christos Exp $"); 1.42 +#endif 1.43 +#endif 1.44 + 1.45 +/* Import. */ 1.46 + 1.47 +#include <sys/types.h> 1.48 +#include <sys/socket.h> 1.49 + 1.50 +#include <netinet/in.h> 1.51 +#include "arpa_nameser.h" 1.52 +#include <arpa/inet.h> 1.53 + 1.54 +#include "assertions.h" 1.55 +#include "dst.h" 1.56 +#include <errno.h> 1.57 +#ifdef ANDROID_CHANGES 1.58 +#include "resolv_private.h" 1.59 +#else 1.60 +#include <resolv.h> 1.61 +#endif 1.62 +#include <string.h> 1.63 +#include <ctype.h> 1.64 +#include <assert.h> 1.65 + 1.66 +#ifdef SPRINTF_CHAR 1.67 +# define SPRINTF(x) strlen(sprintf/**/x) 1.68 +#else 1.69 +# define SPRINTF(x) ((size_t)sprintf x) 1.70 +#endif 1.71 + 1.72 +#ifndef MIN 1.73 +#define MIN(x,y) ((x)<(y)?(x):(y)) 1.74 +#endif 1.75 + 1.76 +/* Forward. */ 1.77 + 1.78 +static size_t prune_origin(const char *name, const char *origin); 1.79 +static int charstr(const u_char *rdata, const u_char *edata, 1.80 + char **buf, size_t *buflen); 1.81 +static int addname(const u_char *msg, size_t msglen, 1.82 + const u_char **p, const char *origin, 1.83 + char **buf, size_t *buflen); 1.84 +static void addlen(size_t len, char **buf, size_t *buflen); 1.85 +static int addstr(const char *src, size_t len, 1.86 + char **buf, size_t *buflen); 1.87 +static int addtab(size_t len, size_t target, int spaced, 1.88 + char **buf, size_t *buflen); 1.89 + 1.90 +/* Macros. */ 1.91 + 1.92 +#define T(x) \ 1.93 + do { \ 1.94 + if ((x) < 0) \ 1.95 + return (-1); \ 1.96 + } while (/*CONSTCOND*/0) 1.97 + 1.98 +/* Public. */ 1.99 + 1.100 +/* 1.101 + * int 1.102 + * ns_sprintrr(handle, rr, name_ctx, origin, buf, buflen) 1.103 + * Convert an RR to presentation format. 1.104 + * return: 1.105 + * Number of characters written to buf, or -1 (check errno). 1.106 + */ 1.107 +int 1.108 +ns_sprintrr(const ns_msg *handle, const ns_rr *rr, 1.109 + const char *name_ctx, const char *origin, 1.110 + char *buf, size_t buflen) 1.111 +{ 1.112 + int n; 1.113 + 1.114 + n = ns_sprintrrf(ns_msg_base(*handle), ns_msg_size(*handle), 1.115 + ns_rr_name(*rr), ns_rr_class(*rr), ns_rr_type(*rr), 1.116 + ns_rr_ttl(*rr), ns_rr_rdata(*rr), ns_rr_rdlen(*rr), 1.117 + name_ctx, origin, buf, buflen); 1.118 + return (n); 1.119 +} 1.120 + 1.121 +/* 1.122 + * int 1.123 + * ns_sprintrrf(msg, msglen, name, class, type, ttl, rdata, rdlen, 1.124 + * name_ctx, origin, buf, buflen) 1.125 + * Convert the fields of an RR into presentation format. 1.126 + * return: 1.127 + * Number of characters written to buf, or -1 (check errno). 1.128 + */ 1.129 +int 1.130 +ns_sprintrrf(const u_char *msg, size_t msglen, 1.131 + const char *name, ns_class class, ns_type type, 1.132 + u_long ttl, const u_char *rdata, size_t rdlen, 1.133 + const char *name_ctx, const char *origin, 1.134 + char *buf, size_t buflen) 1.135 +{ 1.136 + const char *obuf = buf; 1.137 + const u_char *edata = rdata + rdlen; 1.138 + int spaced = 0; 1.139 + 1.140 + const char *comment; 1.141 + char tmp[100]; 1.142 + int len, x; 1.143 + 1.144 + /* 1.145 + * Owner. 1.146 + */ 1.147 + if (name_ctx != NULL && ns_samename(name_ctx, name) == 1) { 1.148 + T(addstr("\t\t\t", (size_t)3, &buf, &buflen)); 1.149 + } else { 1.150 + len = prune_origin(name, origin); 1.151 + if (*name == '\0') { 1.152 + goto root; 1.153 + } else if (len == 0) { 1.154 + T(addstr("@\t\t\t", (size_t)4, &buf, &buflen)); 1.155 + } else { 1.156 + T(addstr(name, (size_t)len, &buf, &buflen)); 1.157 + /* Origin not used or not root, and no trailing dot? */ 1.158 + if (((origin == NULL || origin[0] == '\0') || 1.159 + (origin[0] != '.' && origin[1] != '\0' && 1.160 + name[len] == '\0')) && name[len - 1] != '.') { 1.161 + root: 1.162 + T(addstr(".", (size_t)1, &buf, &buflen)); 1.163 + len++; 1.164 + } 1.165 + T(spaced = addtab((size_t)len, 24, spaced, &buf, &buflen)); 1.166 + } 1.167 + } 1.168 + 1.169 + /* 1.170 + * TTL, Class, Type. 1.171 + */ 1.172 + T(x = ns_format_ttl(ttl, buf, buflen)); 1.173 + addlen((size_t)x, &buf, &buflen); 1.174 + len = SPRINTF((tmp, " %s %s", p_class(class), p_type(type))); 1.175 + T(addstr(tmp, (size_t)len, &buf, &buflen)); 1.176 + T(spaced = addtab((size_t)(x + len), (size_t)16, spaced, &buf, &buflen)); 1.177 + 1.178 + /* 1.179 + * RData. 1.180 + */ 1.181 + switch (type) { 1.182 + case ns_t_a: 1.183 + if (rdlen != (size_t)NS_INADDRSZ) 1.184 + goto formerr; 1.185 + (void) inet_ntop(AF_INET, rdata, buf, buflen); 1.186 + addlen(strlen(buf), &buf, &buflen); 1.187 + break; 1.188 + 1.189 + case ns_t_cname: 1.190 + case ns_t_mb: 1.191 + case ns_t_mg: 1.192 + case ns_t_mr: 1.193 + case ns_t_ns: 1.194 + case ns_t_ptr: 1.195 + case ns_t_dname: 1.196 + T(addname(msg, msglen, &rdata, origin, &buf, &buflen)); 1.197 + break; 1.198 + 1.199 + case ns_t_hinfo: 1.200 + case ns_t_isdn: 1.201 + /* First word. */ 1.202 + T(len = charstr(rdata, edata, &buf, &buflen)); 1.203 + if (len == 0) 1.204 + goto formerr; 1.205 + rdata += len; 1.206 + T(addstr(" ", (size_t)1, &buf, &buflen)); 1.207 + 1.208 + 1.209 + /* Second word, optional in ISDN records. */ 1.210 + if (type == ns_t_isdn && rdata == edata) 1.211 + break; 1.212 + 1.213 + T(len = charstr(rdata, edata, &buf, &buflen)); 1.214 + if (len == 0) 1.215 + goto formerr; 1.216 + rdata += len; 1.217 + break; 1.218 + 1.219 + case ns_t_soa: { 1.220 + u_long t; 1.221 + 1.222 + /* Server name. */ 1.223 + T(addname(msg, msglen, &rdata, origin, &buf, &buflen)); 1.224 + T(addstr(" ", (size_t)1, &buf, &buflen)); 1.225 + 1.226 + /* Administrator name. */ 1.227 + T(addname(msg, msglen, &rdata, origin, &buf, &buflen)); 1.228 + T(addstr(" (\n", (size_t)3, &buf, &buflen)); 1.229 + spaced = 0; 1.230 + 1.231 + if ((edata - rdata) != 5*NS_INT32SZ) 1.232 + goto formerr; 1.233 + 1.234 + /* Serial number. */ 1.235 + t = ns_get32(rdata); rdata += NS_INT32SZ; 1.236 + T(addstr("\t\t\t\t\t", (size_t)5, &buf, &buflen)); 1.237 + len = SPRINTF((tmp, "%lu", t)); 1.238 + T(addstr(tmp, (size_t)len, &buf, &buflen)); 1.239 + T(spaced = addtab((size_t)len, (size_t)16, spaced, &buf, &buflen)); 1.240 + T(addstr("; serial\n", (size_t)9, &buf, &buflen)); 1.241 + spaced = 0; 1.242 + 1.243 + /* Refresh interval. */ 1.244 + t = ns_get32(rdata); rdata += NS_INT32SZ; 1.245 + T(addstr("\t\t\t\t\t", (size_t)5, &buf, &buflen)); 1.246 + T(len = ns_format_ttl(t, buf, buflen)); 1.247 + addlen((size_t)len, &buf, &buflen); 1.248 + T(spaced = addtab((size_t)len, (size_t)16, spaced, &buf, &buflen)); 1.249 + T(addstr("; refresh\n", (size_t)10, &buf, &buflen)); 1.250 + spaced = 0; 1.251 + 1.252 + /* Retry interval. */ 1.253 + t = ns_get32(rdata); rdata += NS_INT32SZ; 1.254 + T(addstr("\t\t\t\t\t", (size_t)5, &buf, &buflen)); 1.255 + T(len = ns_format_ttl(t, buf, buflen)); 1.256 + addlen((size_t)len, &buf, &buflen); 1.257 + T(spaced = addtab((size_t)len, (size_t)16, spaced, &buf, &buflen)); 1.258 + T(addstr("; retry\n", (size_t)8, &buf, &buflen)); 1.259 + spaced = 0; 1.260 + 1.261 + /* Expiry. */ 1.262 + t = ns_get32(rdata); rdata += NS_INT32SZ; 1.263 + T(addstr("\t\t\t\t\t", (size_t)5, &buf, &buflen)); 1.264 + T(len = ns_format_ttl(t, buf, buflen)); 1.265 + addlen((size_t)len, &buf, &buflen); 1.266 + T(spaced = addtab((size_t)len, (size_t)16, spaced, &buf, &buflen)); 1.267 + T(addstr("; expiry\n", (size_t)9, &buf, &buflen)); 1.268 + spaced = 0; 1.269 + 1.270 + /* Minimum TTL. */ 1.271 + t = ns_get32(rdata); rdata += NS_INT32SZ; 1.272 + T(addstr("\t\t\t\t\t", (size_t)5, &buf, &buflen)); 1.273 + T(len = ns_format_ttl(t, buf, buflen)); 1.274 + addlen((size_t)len, &buf, &buflen); 1.275 + T(addstr(" )", (size_t)2, &buf, &buflen)); 1.276 + T(spaced = addtab((size_t)len, (size_t)16, spaced, &buf, &buflen)); 1.277 + T(addstr("; minimum\n", (size_t)10, &buf, &buflen)); 1.278 + 1.279 + break; 1.280 + } 1.281 + 1.282 + case ns_t_mx: 1.283 + case ns_t_afsdb: 1.284 + case ns_t_rt: { 1.285 + u_int t; 1.286 + 1.287 + if (rdlen < (size_t)NS_INT16SZ) 1.288 + goto formerr; 1.289 + 1.290 + /* Priority. */ 1.291 + t = ns_get16(rdata); 1.292 + rdata += NS_INT16SZ; 1.293 + len = SPRINTF((tmp, "%u ", t)); 1.294 + T(addstr(tmp, (size_t)len, &buf, &buflen)); 1.295 + 1.296 + /* Target. */ 1.297 + T(addname(msg, msglen, &rdata, origin, &buf, &buflen)); 1.298 + 1.299 + break; 1.300 + } 1.301 + 1.302 + case ns_t_px: { 1.303 + u_int t; 1.304 + 1.305 + if (rdlen < (size_t)NS_INT16SZ) 1.306 + goto formerr; 1.307 + 1.308 + /* Priority. */ 1.309 + t = ns_get16(rdata); 1.310 + rdata += NS_INT16SZ; 1.311 + len = SPRINTF((tmp, "%u ", t)); 1.312 + T(addstr(tmp, (size_t)len, &buf, &buflen)); 1.313 + 1.314 + /* Name1. */ 1.315 + T(addname(msg, msglen, &rdata, origin, &buf, &buflen)); 1.316 + T(addstr(" ", (size_t)1, &buf, &buflen)); 1.317 + 1.318 + /* Name2. */ 1.319 + T(addname(msg, msglen, &rdata, origin, &buf, &buflen)); 1.320 + 1.321 + break; 1.322 + } 1.323 + 1.324 + case ns_t_x25: 1.325 + T(len = charstr(rdata, edata, &buf, &buflen)); 1.326 + if (len == 0) 1.327 + goto formerr; 1.328 + rdata += len; 1.329 + break; 1.330 + 1.331 + case ns_t_txt: 1.332 + while (rdata < edata) { 1.333 + T(len = charstr(rdata, edata, &buf, &buflen)); 1.334 + if (len == 0) 1.335 + goto formerr; 1.336 + rdata += len; 1.337 + if (rdata < edata) 1.338 + T(addstr(" ", (size_t)1, &buf, &buflen)); 1.339 + } 1.340 + break; 1.341 + 1.342 + case ns_t_nsap: { 1.343 + char t[2+255*3]; 1.344 + 1.345 + (void) inet_nsap_ntoa((int)rdlen, rdata, t); 1.346 + T(addstr(t, strlen(t), &buf, &buflen)); 1.347 + break; 1.348 + } 1.349 + 1.350 + case ns_t_aaaa: 1.351 + if (rdlen != (size_t)NS_IN6ADDRSZ) 1.352 + goto formerr; 1.353 + (void) inet_ntop(AF_INET6, rdata, buf, buflen); 1.354 + addlen(strlen(buf), &buf, &buflen); 1.355 + break; 1.356 + 1.357 + case ns_t_loc: { 1.358 + char t[255]; 1.359 + 1.360 + /* XXX protocol format checking? */ 1.361 + (void) loc_ntoa(rdata, t); 1.362 + T(addstr(t, strlen(t), &buf, &buflen)); 1.363 + break; 1.364 + } 1.365 + 1.366 + case ns_t_naptr: { 1.367 + u_int order, preference; 1.368 + char t[50]; 1.369 + 1.370 + if (rdlen < 2U*NS_INT16SZ) 1.371 + goto formerr; 1.372 + 1.373 + /* Order, Precedence. */ 1.374 + order = ns_get16(rdata); rdata += NS_INT16SZ; 1.375 + preference = ns_get16(rdata); rdata += NS_INT16SZ; 1.376 + len = SPRINTF((t, "%u %u ", order, preference)); 1.377 + T(addstr(t, (size_t)len, &buf, &buflen)); 1.378 + 1.379 + /* Flags. */ 1.380 + T(len = charstr(rdata, edata, &buf, &buflen)); 1.381 + if (len == 0) 1.382 + goto formerr; 1.383 + rdata += len; 1.384 + T(addstr(" ", (size_t)1, &buf, &buflen)); 1.385 + 1.386 + /* Service. */ 1.387 + T(len = charstr(rdata, edata, &buf, &buflen)); 1.388 + if (len == 0) 1.389 + goto formerr; 1.390 + rdata += len; 1.391 + T(addstr(" ", (size_t)1, &buf, &buflen)); 1.392 + 1.393 + /* Regexp. */ 1.394 + T(len = charstr(rdata, edata, &buf, &buflen)); 1.395 + if (len < 0) 1.396 + return (-1); 1.397 + if (len == 0) 1.398 + goto formerr; 1.399 + rdata += len; 1.400 + T(addstr(" ", (size_t)1, &buf, &buflen)); 1.401 + 1.402 + /* Server. */ 1.403 + T(addname(msg, msglen, &rdata, origin, &buf, &buflen)); 1.404 + break; 1.405 + } 1.406 + 1.407 + case ns_t_srv: { 1.408 + u_int priority, weight, port; 1.409 + char t[50]; 1.410 + 1.411 + if (rdlen < 3U*NS_INT16SZ) 1.412 + goto formerr; 1.413 + 1.414 + /* Priority, Weight, Port. */ 1.415 + priority = ns_get16(rdata); rdata += NS_INT16SZ; 1.416 + weight = ns_get16(rdata); rdata += NS_INT16SZ; 1.417 + port = ns_get16(rdata); rdata += NS_INT16SZ; 1.418 + len = SPRINTF((t, "%u %u %u ", priority, weight, port)); 1.419 + T(addstr(t, (size_t)len, &buf, &buflen)); 1.420 + 1.421 + /* Server. */ 1.422 + T(addname(msg, msglen, &rdata, origin, &buf, &buflen)); 1.423 + break; 1.424 + } 1.425 + 1.426 + case ns_t_minfo: 1.427 + case ns_t_rp: 1.428 + /* Name1. */ 1.429 + T(addname(msg, msglen, &rdata, origin, &buf, &buflen)); 1.430 + T(addstr(" ", (size_t)1, &buf, &buflen)); 1.431 + 1.432 + /* Name2. */ 1.433 + T(addname(msg, msglen, &rdata, origin, &buf, &buflen)); 1.434 + 1.435 + break; 1.436 + 1.437 + case ns_t_wks: { 1.438 + int n, lcnt; 1.439 + 1.440 + if (rdlen < 1U + NS_INT32SZ) 1.441 + goto formerr; 1.442 + 1.443 + /* Address. */ 1.444 + (void) inet_ntop(AF_INET, rdata, buf, buflen); 1.445 + addlen(strlen(buf), &buf, &buflen); 1.446 + rdata += NS_INADDRSZ; 1.447 + 1.448 + /* Protocol. */ 1.449 + len = SPRINTF((tmp, " %u ( ", *rdata)); 1.450 + T(addstr(tmp, (size_t)len, &buf, &buflen)); 1.451 + rdata += NS_INT8SZ; 1.452 + 1.453 + /* Bit map. */ 1.454 + n = 0; 1.455 + lcnt = 0; 1.456 + while (rdata < edata) { 1.457 + u_int c = *rdata++; 1.458 + do { 1.459 + if (c & 0200) { 1.460 + if (lcnt == 0) { 1.461 + T(addstr("\n\t\t\t\t", (size_t)5, 1.462 + &buf, &buflen)); 1.463 + lcnt = 10; 1.464 + spaced = 0; 1.465 + } 1.466 + len = SPRINTF((tmp, "%d ", n)); 1.467 + T(addstr(tmp, (size_t)len, &buf, &buflen)); 1.468 + lcnt--; 1.469 + } 1.470 + c <<= 1; 1.471 + } while (++n & 07); 1.472 + } 1.473 + T(addstr(")", (size_t)1, &buf, &buflen)); 1.474 + 1.475 + break; 1.476 + } 1.477 + 1.478 + case ns_t_key: { 1.479 + char base64_key[NS_MD5RSA_MAX_BASE64]; 1.480 + u_int keyflags, protocol, algorithm, key_id; 1.481 + const char *leader; 1.482 + int n; 1.483 + 1.484 + if (rdlen < 0U + NS_INT16SZ + NS_INT8SZ + NS_INT8SZ) 1.485 + goto formerr; 1.486 + 1.487 + /* Key flags, Protocol, Algorithm. */ 1.488 +#if !defined(MOZILLA_NECKO_EXCLUDE_CODE) && !defined(_LIBC) 1.489 + key_id = dst_s_dns_key_id(rdata, edata-rdata); 1.490 +#else 1.491 + key_id = 0; 1.492 +#endif 1.493 + keyflags = ns_get16(rdata); rdata += NS_INT16SZ; 1.494 + protocol = *rdata++; 1.495 + algorithm = *rdata++; 1.496 + len = SPRINTF((tmp, "0x%04x %u %u", 1.497 + keyflags, protocol, algorithm)); 1.498 + T(addstr(tmp, (size_t)len, &buf, &buflen)); 1.499 + 1.500 + /* Public key data. */ 1.501 + len = b64_ntop(rdata, (size_t)(edata - rdata), 1.502 + base64_key, sizeof base64_key); 1.503 + if (len < 0) 1.504 + goto formerr; 1.505 + if (len > 15) { 1.506 + T(addstr(" (", (size_t)2, &buf, &buflen)); 1.507 + leader = "\n\t\t"; 1.508 + spaced = 0; 1.509 + } else 1.510 + leader = " "; 1.511 + for (n = 0; n < len; n += 48) { 1.512 + T(addstr(leader, strlen(leader), &buf, &buflen)); 1.513 + T(addstr(base64_key + n, (size_t)MIN(len - n, 48), 1.514 + &buf, &buflen)); 1.515 + } 1.516 + if (len > 15) 1.517 + T(addstr(" )", (size_t)2, &buf, &buflen)); 1.518 + n = SPRINTF((tmp, " ; key_tag= %u", key_id)); 1.519 + T(addstr(tmp, (size_t)n, &buf, &buflen)); 1.520 + 1.521 + break; 1.522 + } 1.523 + 1.524 + case ns_t_sig: { 1.525 + char base64_key[NS_MD5RSA_MAX_BASE64]; 1.526 + u_int typ, algorithm, labels, footprint; 1.527 + const char *leader; 1.528 + u_long t; 1.529 + int n; 1.530 + 1.531 + if (rdlen < 22U) 1.532 + goto formerr; 1.533 + 1.534 + /* Type covered, Algorithm, Label count, Original TTL. */ 1.535 + typ = ns_get16(rdata); rdata += NS_INT16SZ; 1.536 + algorithm = *rdata++; 1.537 + labels = *rdata++; 1.538 + t = ns_get32(rdata); rdata += NS_INT32SZ; 1.539 + len = SPRINTF((tmp, "%s %d %d %lu ", 1.540 + p_type((int)typ), algorithm, labels, t)); 1.541 + T(addstr(tmp, (size_t)len, &buf, &buflen)); 1.542 + if (labels > (u_int)dn_count_labels(name)) 1.543 + goto formerr; 1.544 + 1.545 + /* Signature expiry. */ 1.546 + t = ns_get32(rdata); rdata += NS_INT32SZ; 1.547 + len = SPRINTF((tmp, "%s ", p_secstodate(t))); 1.548 + T(addstr(tmp, (size_t)len, &buf, &buflen)); 1.549 + 1.550 + /* Time signed. */ 1.551 + t = ns_get32(rdata); rdata += NS_INT32SZ; 1.552 + len = SPRINTF((tmp, "%s ", p_secstodate(t))); 1.553 + T(addstr(tmp, (size_t)len, &buf, &buflen)); 1.554 + 1.555 + /* Signature Footprint. */ 1.556 + footprint = ns_get16(rdata); rdata += NS_INT16SZ; 1.557 + len = SPRINTF((tmp, "%u ", footprint)); 1.558 + T(addstr(tmp, (size_t)len, &buf, &buflen)); 1.559 + 1.560 + /* Signer's name. */ 1.561 + T(addname(msg, msglen, &rdata, origin, &buf, &buflen)); 1.562 + 1.563 + /* Signature. */ 1.564 + len = b64_ntop(rdata, (size_t)(edata - rdata), 1.565 + base64_key, sizeof base64_key); 1.566 + if (len > 15) { 1.567 + T(addstr(" (", (size_t)2, &buf, &buflen)); 1.568 + leader = "\n\t\t"; 1.569 + spaced = 0; 1.570 + } else 1.571 + leader = " "; 1.572 + if (len < 0) 1.573 + goto formerr; 1.574 + for (n = 0; n < len; n += 48) { 1.575 + T(addstr(leader, strlen(leader), &buf, &buflen)); 1.576 + T(addstr(base64_key + n, (size_t)MIN(len - n, 48), 1.577 + &buf, &buflen)); 1.578 + } 1.579 + if (len > 15) 1.580 + T(addstr(" )", (size_t)2, &buf, &buflen)); 1.581 + break; 1.582 + } 1.583 + 1.584 + case ns_t_nxt: { 1.585 + int n, c; 1.586 + 1.587 + /* Next domain name. */ 1.588 + T(addname(msg, msglen, &rdata, origin, &buf, &buflen)); 1.589 + 1.590 + /* Type bit map. */ 1.591 + n = edata - rdata; 1.592 + for (c = 0; c < n*8; c++) 1.593 + if (NS_NXT_BIT_ISSET(c, rdata)) { 1.594 + len = SPRINTF((tmp, " %s", p_type(c))); 1.595 + T(addstr(tmp, (size_t)len, &buf, &buflen)); 1.596 + } 1.597 + break; 1.598 + } 1.599 + 1.600 + case ns_t_cert: { 1.601 + u_int c_type, key_tag, alg; 1.602 + int n; 1.603 + unsigned int siz; 1.604 + char base64_cert[8192], tmp1[40]; 1.605 + const char *leader; 1.606 + 1.607 + c_type = ns_get16(rdata); rdata += NS_INT16SZ; 1.608 + key_tag = ns_get16(rdata); rdata += NS_INT16SZ; 1.609 + alg = (u_int) *rdata++; 1.610 + 1.611 + len = SPRINTF((tmp1, "%d %d %d ", c_type, key_tag, alg)); 1.612 + T(addstr(tmp1, (size_t)len, &buf, &buflen)); 1.613 + siz = (edata-rdata)*4/3 + 4; /* "+4" accounts for trailing \0 */ 1.614 + if (siz > sizeof(base64_cert) * 3/4) { 1.615 + const char *str = "record too long to print"; 1.616 + T(addstr(str, strlen(str), &buf, &buflen)); 1.617 + } 1.618 + else { 1.619 + len = b64_ntop(rdata, (size_t)(edata-rdata), 1.620 + base64_cert, siz); 1.621 + 1.622 + if (len < 0) 1.623 + goto formerr; 1.624 + else if (len > 15) { 1.625 + T(addstr(" (", (size_t)2, &buf, &buflen)); 1.626 + leader = "\n\t\t"; 1.627 + spaced = 0; 1.628 + } 1.629 + else 1.630 + leader = " "; 1.631 + 1.632 + for (n = 0; n < len; n += 48) { 1.633 + T(addstr(leader, strlen(leader), 1.634 + &buf, &buflen)); 1.635 + T(addstr(base64_cert + n, (size_t)MIN(len - n, 48), 1.636 + &buf, &buflen)); 1.637 + } 1.638 + if (len > 15) 1.639 + T(addstr(" )", (size_t)2, &buf, &buflen)); 1.640 + } 1.641 + break; 1.642 + } 1.643 + 1.644 + case ns_t_tkey: { 1.645 + /* KJD - need to complete this */ 1.646 + u_long t; 1.647 + int mode, err, keysize; 1.648 + 1.649 + /* Algorithm name. */ 1.650 + T(addname(msg, msglen, &rdata, origin, &buf, &buflen)); 1.651 + T(addstr(" ", (size_t)1, &buf, &buflen)); 1.652 + 1.653 + /* Inception. */ 1.654 + t = ns_get32(rdata); rdata += NS_INT32SZ; 1.655 + len = SPRINTF((tmp, "%s ", p_secstodate(t))); 1.656 + T(addstr(tmp, (size_t)len, &buf, &buflen)); 1.657 + 1.658 + /* Experation. */ 1.659 + t = ns_get32(rdata); rdata += NS_INT32SZ; 1.660 + len = SPRINTF((tmp, "%s ", p_secstodate(t))); 1.661 + T(addstr(tmp, (size_t)len, &buf, &buflen)); 1.662 + 1.663 + /* Mode , Error, Key Size. */ 1.664 + /* Priority, Weight, Port. */ 1.665 + mode = ns_get16(rdata); rdata += NS_INT16SZ; 1.666 + err = ns_get16(rdata); rdata += NS_INT16SZ; 1.667 + keysize = ns_get16(rdata); rdata += NS_INT16SZ; 1.668 + len = SPRINTF((tmp, "%u %u %u ", mode, err, keysize)); 1.669 + T(addstr(tmp, (size_t)len, &buf, &buflen)); 1.670 + 1.671 + /* XXX need to dump key, print otherdata length & other data */ 1.672 + break; 1.673 + } 1.674 + 1.675 + case ns_t_tsig: { 1.676 + /* BEW - need to complete this */ 1.677 + int n; 1.678 + 1.679 + T(len = addname(msg, msglen, &rdata, origin, &buf, &buflen)); 1.680 + T(addstr(" ", (size_t)1, &buf, &buflen)); 1.681 + rdata += 8; /* time */ 1.682 + n = ns_get16(rdata); rdata += INT16SZ; 1.683 + rdata += n; /* sig */ 1.684 + n = ns_get16(rdata); rdata += INT16SZ; /* original id */ 1.685 + sprintf(buf, "%d", ns_get16(rdata)); 1.686 + rdata += INT16SZ; 1.687 + addlen(strlen(buf), &buf, &buflen); 1.688 + break; 1.689 + } 1.690 + 1.691 + case ns_t_a6: { 1.692 + struct in6_addr a; 1.693 + int pbyte, pbit; 1.694 + 1.695 + /* prefix length */ 1.696 + if (rdlen == 0U) goto formerr; 1.697 + len = SPRINTF((tmp, "%d ", *rdata)); 1.698 + T(addstr(tmp, (size_t)len, &buf, &buflen)); 1.699 + pbit = *rdata; 1.700 + if (pbit > 128) goto formerr; 1.701 + pbyte = (pbit & ~7) / 8; 1.702 + rdata++; 1.703 + 1.704 + /* address suffix: provided only when prefix len != 128 */ 1.705 + if (pbit < 128) { 1.706 + if (rdata + pbyte >= edata) goto formerr; 1.707 + memset(&a, 0, sizeof(a)); 1.708 + memcpy(&a.s6_addr[pbyte], rdata, sizeof(a) - pbyte); 1.709 + (void) inet_ntop(AF_INET6, &a, buf, buflen); 1.710 + addlen(strlen(buf), &buf, &buflen); 1.711 + rdata += sizeof(a) - pbyte; 1.712 + } 1.713 + 1.714 + /* prefix name: provided only when prefix len > 0 */ 1.715 + if (pbit == 0) 1.716 + break; 1.717 + if (rdata >= edata) goto formerr; 1.718 + T(addstr(" ", (size_t)1, &buf, &buflen)); 1.719 + T(addname(msg, msglen, &rdata, origin, &buf, &buflen)); 1.720 + 1.721 + break; 1.722 + } 1.723 + 1.724 + case ns_t_opt: { 1.725 + len = SPRINTF((tmp, "%u bytes", class)); 1.726 + T(addstr(tmp, (size_t)len, &buf, &buflen)); 1.727 + break; 1.728 + } 1.729 + 1.730 + default: 1.731 + comment = "unknown RR type"; 1.732 + goto hexify; 1.733 + } 1.734 + return (buf - obuf); 1.735 + formerr: 1.736 + comment = "RR format error"; 1.737 + hexify: { 1.738 + int n, m; 1.739 + char *p; 1.740 + 1.741 + len = SPRINTF((tmp, "\\# %tu%s\t; %s", edata - rdata, 1.742 + rdlen != 0 ? " (" : "", comment)); 1.743 + T(addstr(tmp, (size_t)len, &buf, &buflen)); 1.744 + while (rdata < edata) { 1.745 + p = tmp; 1.746 + p += SPRINTF((p, "\n\t")); 1.747 + spaced = 0; 1.748 + n = MIN(16, edata - rdata); 1.749 + for (m = 0; m < n; m++) 1.750 + p += SPRINTF((p, "%02x ", rdata[m])); 1.751 + T(addstr(tmp, (size_t)(p - tmp), &buf, &buflen)); 1.752 + if (n < 16) { 1.753 + T(addstr(")", (size_t)1, &buf, &buflen)); 1.754 + T(addtab((size_t)(p - tmp + 1), (size_t)48, spaced, &buf, &buflen)); 1.755 + } 1.756 + p = tmp; 1.757 + p += SPRINTF((p, "; ")); 1.758 + for (m = 0; m < n; m++) 1.759 + *p++ = (isascii(rdata[m]) && isprint(rdata[m])) 1.760 + ? rdata[m] 1.761 + : '.'; 1.762 + T(addstr(tmp, (size_t)(p - tmp), &buf, &buflen)); 1.763 + rdata += n; 1.764 + } 1.765 + return (buf - obuf); 1.766 + } 1.767 +} 1.768 + 1.769 +/* Private. */ 1.770 + 1.771 +/* 1.772 + * size_t 1.773 + * prune_origin(name, origin) 1.774 + * Find out if the name is at or under the current origin. 1.775 + * return: 1.776 + * Number of characters in name before start of origin, 1.777 + * or length of name if origin does not match. 1.778 + * notes: 1.779 + * This function should share code with samedomain(). 1.780 + */ 1.781 +static size_t 1.782 +prune_origin(const char *name, const char *origin) { 1.783 + const char *oname = name; 1.784 + 1.785 + while (*name != '\0') { 1.786 + if (origin != NULL && ns_samename(name, origin) == 1) 1.787 + return (name - oname - (name > oname)); 1.788 + while (*name != '\0') { 1.789 + if (*name == '\\') { 1.790 + name++; 1.791 + /* XXX need to handle \nnn form. */ 1.792 + if (*name == '\0') 1.793 + break; 1.794 + } else if (*name == '.') { 1.795 + name++; 1.796 + break; 1.797 + } 1.798 + name++; 1.799 + } 1.800 + } 1.801 + return (name - oname); 1.802 +} 1.803 + 1.804 +/* 1.805 + * int 1.806 + * charstr(rdata, edata, buf, buflen) 1.807 + * Format a <character-string> into the presentation buffer. 1.808 + * return: 1.809 + * Number of rdata octets consumed 1.810 + * 0 for protocol format error 1.811 + * -1 for output buffer error 1.812 + * side effects: 1.813 + * buffer is advanced on success. 1.814 + */ 1.815 +static int 1.816 +charstr(const u_char *rdata, const u_char *edata, char **buf, size_t *buflen) { 1.817 + const u_char *odata = rdata; 1.818 + size_t save_buflen = *buflen; 1.819 + char *save_buf = *buf; 1.820 + 1.821 + if (addstr("\"", (size_t)1, buf, buflen) < 0) 1.822 + goto enospc; 1.823 + if (rdata < edata) { 1.824 + int n = *rdata; 1.825 + 1.826 + if (rdata + 1 + n <= edata) { 1.827 + rdata++; 1.828 + while (n-- > 0) { 1.829 + if (strchr("\n\"\\", *rdata) != NULL) 1.830 + if (addstr("\\", (size_t)1, buf, buflen) < 0) 1.831 + goto enospc; 1.832 + if (addstr((const char *)rdata, (size_t)1, 1.833 + buf, buflen) < 0) 1.834 + goto enospc; 1.835 + rdata++; 1.836 + } 1.837 + } 1.838 + } 1.839 + if (addstr("\"", (size_t)1, buf, buflen) < 0) 1.840 + goto enospc; 1.841 + return (rdata - odata); 1.842 + enospc: 1.843 + errno = ENOSPC; 1.844 + *buf = save_buf; 1.845 + *buflen = save_buflen; 1.846 + return (-1); 1.847 +} 1.848 + 1.849 +static int 1.850 +addname(const u_char *msg, size_t msglen, 1.851 + const u_char **pp, const char *origin, 1.852 + char **buf, size_t *buflen) 1.853 +{ 1.854 + size_t newlen, save_buflen = *buflen; 1.855 + char *save_buf = *buf; 1.856 + int n; 1.857 + 1.858 + n = dn_expand(msg, msg + msglen, *pp, *buf, (int)*buflen); 1.859 + if (n < 0) 1.860 + goto enospc; /* Guess. */ 1.861 + newlen = prune_origin(*buf, origin); 1.862 + if (**buf == '\0') { 1.863 + goto root; 1.864 + } else if (newlen == 0U) { 1.865 + /* Use "@" instead of name. */ 1.866 + if (newlen + 2 > *buflen) 1.867 + goto enospc; /* No room for "@\0". */ 1.868 + (*buf)[newlen++] = '@'; 1.869 + (*buf)[newlen] = '\0'; 1.870 + } else { 1.871 + if (((origin == NULL || origin[0] == '\0') || 1.872 + (origin[0] != '.' && origin[1] != '\0' && 1.873 + (*buf)[newlen] == '\0')) && (*buf)[newlen - 1] != '.') { 1.874 + /* No trailing dot. */ 1.875 + root: 1.876 + if (newlen + 2 > *buflen) 1.877 + goto enospc; /* No room for ".\0". */ 1.878 + (*buf)[newlen++] = '.'; 1.879 + (*buf)[newlen] = '\0'; 1.880 + } 1.881 + } 1.882 + *pp += n; 1.883 + addlen(newlen, buf, buflen); 1.884 + **buf = '\0'; 1.885 + return (newlen); 1.886 + enospc: 1.887 + errno = ENOSPC; 1.888 + *buf = save_buf; 1.889 + *buflen = save_buflen; 1.890 + return (-1); 1.891 +} 1.892 + 1.893 +static void 1.894 +addlen(size_t len, char **buf, size_t *buflen) { 1.895 + assert(len <= *buflen); 1.896 + *buf += len; 1.897 + *buflen -= len; 1.898 +} 1.899 + 1.900 +static int 1.901 +addstr(const char *src, size_t len, char **buf, size_t *buflen) { 1.902 + if (len >= *buflen) { 1.903 + errno = ENOSPC; 1.904 + return (-1); 1.905 + } 1.906 + memcpy(*buf, src, len); 1.907 + addlen(len, buf, buflen); 1.908 + **buf = '\0'; 1.909 + return (0); 1.910 +} 1.911 + 1.912 +static int 1.913 +addtab(size_t len, size_t target, int spaced, char **buf, size_t *buflen) { 1.914 + size_t save_buflen = *buflen; 1.915 + char *save_buf = *buf; 1.916 + int t; 1.917 + 1.918 + if (spaced || len >= target - 1) { 1.919 + T(addstr(" ", (size_t)2, buf, buflen)); 1.920 + spaced = 1; 1.921 + } else { 1.922 + for (t = (target - len - 1) / 8; t >= 0; t--) 1.923 + if (addstr("\t", (size_t)1, buf, buflen) < 0) { 1.924 + *buflen = save_buflen; 1.925 + *buf = save_buf; 1.926 + return (-1); 1.927 + } 1.928 + spaced = 0; 1.929 + } 1.930 + return (spaced); 1.931 +}