[BACK]Return to ns_print.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / lib / libc / nameser

Annotation of src/lib/libc/nameser/ns_print.c, Revision 1.8.14.1

1.8.14.1! riz         1: /*     $NetBSD: ns_print.c,v 1.10 2009/04/12 19:43:37 christos Exp $   */
1.1       christos    2:
                      3: /*
                      4:  * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
                      5:  * Copyright (c) 1996-1999 by Internet Software Consortium.
                      6:  *
                      7:  * Permission to use, copy, modify, and distribute this software for any
                      8:  * purpose with or without fee is hereby granted, provided that the above
                      9:  * copyright notice and this permission notice appear in all copies.
                     10:  *
                     11:  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
                     12:  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
                     13:  * MERCHANTABILITY AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR
                     14:  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
                     15:  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
                     16:  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
                     17:  * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
                     18:  */
                     19:
1.2       christos   20: #include <sys/cdefs.h>
1.1       christos   21: #ifndef lint
1.2       christos   22: #ifdef notdef
1.8.14.1! riz        23: static const char rcsid[] = "Id: ns_print.c,v 1.12 2009/03/03 05:29:58 each Exp";
1.2       christos   24: #else
1.8.14.1! riz        25: __RCSID("$NetBSD: ns_print.c,v 1.10 2009/04/12 19:43:37 christos Exp $");
1.2       christos   26: #endif
1.1       christos   27: #endif
                     28:
                     29: /* Import. */
                     30:
                     31: #include "port_before.h"
                     32:
                     33: #include <sys/types.h>
                     34: #include <sys/socket.h>
                     35:
                     36: #include <netinet/in.h>
                     37: #include <arpa/nameser.h>
                     38: #include <arpa/inet.h>
                     39:
                     40: #include <isc/assertions.h>
                     41: #include <isc/dst.h>
                     42: #include <errno.h>
                     43: #include <resolv.h>
                     44: #include <string.h>
                     45: #include <ctype.h>
                     46:
                     47: #include "port_after.h"
                     48:
                     49: #ifdef SPRINTF_CHAR
                     50: # define SPRINTF(x) strlen(sprintf/**/x)
                     51: #else
                     52: # define SPRINTF(x) ((size_t)sprintf x)
                     53: #endif
                     54:
                     55: /* Forward. */
                     56:
                     57: static size_t  prune_origin(const char *name, const char *origin);
                     58: static int     charstr(const u_char *rdata, const u_char *edata,
                     59:                        char **buf, size_t *buflen);
                     60: static int     addname(const u_char *msg, size_t msglen,
                     61:                        const u_char **p, const char *origin,
                     62:                        char **buf, size_t *buflen);
                     63: static void    addlen(size_t len, char **buf, size_t *buflen);
                     64: static int     addstr(const char *src, size_t len,
                     65:                       char **buf, size_t *buflen);
                     66: static int     addtab(size_t len, size_t target, int spaced,
                     67:                       char **buf, size_t *buflen);
                     68:
                     69: /* Macros. */
                     70:
                     71: #define        T(x) \
                     72:        do { \
                     73:                if ((x) < 0) \
                     74:                        return (-1); \
1.2       christos   75:        } while (/*CONSTCOND*/0)
1.1       christos   76:
1.8.14.1! riz        77: static const char base32hex[] =
        !            78:         "0123456789ABCDEFGHIJKLMNOPQRSTUV=0123456789abcdefghijklmnopqrstuv";
        !            79:
1.1       christos   80: /* Public. */
                     81:
1.6       christos   82: /*%
1.1       christos   83:  *     Convert an RR to presentation format.
1.6       christos   84:  *
1.1       christos   85:  * return:
1.6       christos   86:  *\li  Number of characters written to buf, or -1 (check errno).
1.1       christos   87:  */
                     88: int
                     89: ns_sprintrr(const ns_msg *handle, const ns_rr *rr,
                     90:            const char *name_ctx, const char *origin,
                     91:            char *buf, size_t buflen)
                     92: {
                     93:        int n;
                     94:
                     95:        n = ns_sprintrrf(ns_msg_base(*handle), ns_msg_size(*handle),
                     96:                         ns_rr_name(*rr), ns_rr_class(*rr), ns_rr_type(*rr),
                     97:                         ns_rr_ttl(*rr), ns_rr_rdata(*rr), ns_rr_rdlen(*rr),
                     98:                         name_ctx, origin, buf, buflen);
                     99:        return (n);
                    100: }
                    101:
1.6       christos  102: /*%
1.1       christos  103:  *     Convert the fields of an RR into presentation format.
1.6       christos  104:  *
1.1       christos  105:  * return:
1.6       christos  106:  *\li  Number of characters written to buf, or -1 (check errno).
1.1       christos  107:  */
                    108: int
                    109: ns_sprintrrf(const u_char *msg, size_t msglen,
                    110:            const char *name, ns_class class, ns_type type,
                    111:            u_long ttl, const u_char *rdata, size_t rdlen,
                    112:            const char *name_ctx, const char *origin,
                    113:            char *buf, size_t buflen)
                    114: {
                    115:        const char *obuf = buf;
                    116:        const u_char *edata = rdata + rdlen;
                    117:        int spaced = 0;
                    118:
                    119:        const char *comment;
                    120:        char tmp[100];
                    121:        int len, x;
                    122:
                    123:        /*
                    124:         * Owner.
                    125:         */
                    126:        if (name_ctx != NULL && ns_samename(name_ctx, name) == 1) {
1.2       christos  127:                T(addstr("\t\t\t", (size_t)3, &buf, &buflen));
1.1       christos  128:        } else {
                    129:                len = prune_origin(name, origin);
                    130:                if (*name == '\0') {
                    131:                        goto root;
                    132:                } else if (len == 0) {
1.2       christos  133:                        T(addstr("@\t\t\t", (size_t)4, &buf, &buflen));
1.1       christos  134:                } else {
1.2       christos  135:                        T(addstr(name, (size_t)len, &buf, &buflen));
1.1       christos  136:                        /* Origin not used or not root, and no trailing dot? */
                    137:                        if (((origin == NULL || origin[0] == '\0') ||
                    138:                            (origin[0] != '.' && origin[1] != '\0' &&
                    139:                            name[len] == '\0')) && name[len - 1] != '.') {
                    140:  root:
1.2       christos  141:                                T(addstr(".", (size_t)1, &buf, &buflen));
1.1       christos  142:                                len++;
                    143:                        }
1.2       christos  144:                        T(spaced = addtab((size_t)len, 24, spaced, &buf, &buflen));
1.1       christos  145:                }
                    146:        }
                    147:
                    148:        /*
                    149:         * TTL, Class, Type.
                    150:         */
                    151:        T(x = ns_format_ttl(ttl, buf, buflen));
1.2       christos  152:        addlen((size_t)x, &buf, &buflen);
1.1       christos  153:        len = SPRINTF((tmp, " %s %s", p_class(class), p_type(type)));
1.2       christos  154:        T(addstr(tmp, (size_t)len, &buf, &buflen));
                    155:        T(spaced = addtab((size_t)(x + len), (size_t)16, spaced, &buf, &buflen));
1.1       christos  156:
                    157:        /*
                    158:         * RData.
                    159:         */
                    160:        switch (type) {
                    161:        case ns_t_a:
                    162:                if (rdlen != (size_t)NS_INADDRSZ)
                    163:                        goto formerr;
                    164:                (void) inet_ntop(AF_INET, rdata, buf, buflen);
                    165:                addlen(strlen(buf), &buf, &buflen);
                    166:                break;
                    167:
                    168:        case ns_t_cname:
                    169:        case ns_t_mb:
                    170:        case ns_t_mg:
                    171:        case ns_t_mr:
                    172:        case ns_t_ns:
                    173:        case ns_t_ptr:
                    174:        case ns_t_dname:
                    175:                T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
                    176:                break;
                    177:
                    178:        case ns_t_hinfo:
                    179:        case ns_t_isdn:
                    180:                /* First word. */
                    181:                T(len = charstr(rdata, edata, &buf, &buflen));
                    182:                if (len == 0)
                    183:                        goto formerr;
                    184:                rdata += len;
1.2       christos  185:                T(addstr(" ", (size_t)1, &buf, &buflen));
1.1       christos  186:
                    187:
                    188:                /* Second word, optional in ISDN records. */
                    189:                if (type == ns_t_isdn && rdata == edata)
                    190:                        break;
                    191:
                    192:                T(len = charstr(rdata, edata, &buf, &buflen));
                    193:                if (len == 0)
                    194:                        goto formerr;
                    195:                rdata += len;
                    196:                break;
                    197:
                    198:        case ns_t_soa: {
                    199:                u_long t;
                    200:
                    201:                /* Server name. */
                    202:                T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
1.2       christos  203:                T(addstr(" ", (size_t)1, &buf, &buflen));
1.1       christos  204:
                    205:                /* Administrator name. */
                    206:                T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
1.2       christos  207:                T(addstr(" (\n", (size_t)3, &buf, &buflen));
1.1       christos  208:                spaced = 0;
                    209:
                    210:                if ((edata - rdata) != 5*NS_INT32SZ)
                    211:                        goto formerr;
                    212:
                    213:                /* Serial number. */
                    214:                t = ns_get32(rdata);  rdata += NS_INT32SZ;
1.2       christos  215:                T(addstr("\t\t\t\t\t", (size_t)5, &buf, &buflen));
1.1       christos  216:                len = SPRINTF((tmp, "%lu", t));
1.2       christos  217:                T(addstr(tmp, (size_t)len, &buf, &buflen));
                    218:                T(spaced = addtab((size_t)len, (size_t)16, spaced, &buf, &buflen));
                    219:                T(addstr("; serial\n", (size_t)9, &buf, &buflen));
1.1       christos  220:                spaced = 0;
                    221:
                    222:                /* Refresh interval. */
                    223:                t = ns_get32(rdata);  rdata += NS_INT32SZ;
1.2       christos  224:                T(addstr("\t\t\t\t\t", (size_t)5, &buf, &buflen));
1.1       christos  225:                T(len = ns_format_ttl(t, buf, buflen));
1.2       christos  226:                addlen((size_t)len, &buf, &buflen);
                    227:                T(spaced = addtab((size_t)len, (size_t)16, spaced, &buf, &buflen));
                    228:                T(addstr("; refresh\n", (size_t)10, &buf, &buflen));
1.1       christos  229:                spaced = 0;
                    230:
                    231:                /* Retry interval. */
                    232:                t = ns_get32(rdata);  rdata += NS_INT32SZ;
1.2       christos  233:                T(addstr("\t\t\t\t\t", (size_t)5, &buf, &buflen));
1.1       christos  234:                T(len = ns_format_ttl(t, buf, buflen));
1.2       christos  235:                addlen((size_t)len, &buf, &buflen);
                    236:                T(spaced = addtab((size_t)len, (size_t)16, spaced, &buf, &buflen));
                    237:                T(addstr("; retry\n", (size_t)8, &buf, &buflen));
1.1       christos  238:                spaced = 0;
                    239:
                    240:                /* Expiry. */
                    241:                t = ns_get32(rdata);  rdata += NS_INT32SZ;
1.2       christos  242:                T(addstr("\t\t\t\t\t", (size_t)5, &buf, &buflen));
1.1       christos  243:                T(len = ns_format_ttl(t, buf, buflen));
1.2       christos  244:                addlen((size_t)len, &buf, &buflen);
                    245:                T(spaced = addtab((size_t)len, (size_t)16, spaced, &buf, &buflen));
                    246:                T(addstr("; expiry\n", (size_t)9, &buf, &buflen));
1.1       christos  247:                spaced = 0;
                    248:
                    249:                /* Minimum TTL. */
                    250:                t = ns_get32(rdata);  rdata += NS_INT32SZ;
1.2       christos  251:                T(addstr("\t\t\t\t\t", (size_t)5, &buf, &buflen));
1.1       christos  252:                T(len = ns_format_ttl(t, buf, buflen));
1.2       christos  253:                addlen((size_t)len, &buf, &buflen);
                    254:                T(addstr(" )", (size_t)2, &buf, &buflen));
                    255:                T(spaced = addtab((size_t)len, (size_t)16, spaced, &buf, &buflen));
                    256:                T(addstr("; minimum\n", (size_t)10, &buf, &buflen));
1.1       christos  257:
                    258:                break;
                    259:            }
                    260:
                    261:        case ns_t_mx:
                    262:        case ns_t_afsdb:
1.8.14.1! riz       263:        case ns_t_rt:
        !           264:        case ns_t_kx: {
1.1       christos  265:                u_int t;
                    266:
                    267:                if (rdlen < (size_t)NS_INT16SZ)
                    268:                        goto formerr;
                    269:
                    270:                /* Priority. */
                    271:                t = ns_get16(rdata);
                    272:                rdata += NS_INT16SZ;
                    273:                len = SPRINTF((tmp, "%u ", t));
1.2       christos  274:                T(addstr(tmp, (size_t)len, &buf, &buflen));
1.1       christos  275:
                    276:                /* Target. */
                    277:                T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
                    278:
                    279:                break;
                    280:            }
                    281:
                    282:        case ns_t_px: {
                    283:                u_int t;
                    284:
                    285:                if (rdlen < (size_t)NS_INT16SZ)
                    286:                        goto formerr;
                    287:
                    288:                /* Priority. */
                    289:                t = ns_get16(rdata);
                    290:                rdata += NS_INT16SZ;
                    291:                len = SPRINTF((tmp, "%u ", t));
1.2       christos  292:                T(addstr(tmp, (size_t)len, &buf, &buflen));
1.1       christos  293:
                    294:                /* Name1. */
                    295:                T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
1.2       christos  296:                T(addstr(" ", (size_t)1, &buf, &buflen));
1.1       christos  297:
                    298:                /* Name2. */
                    299:                T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
                    300:
                    301:                break;
                    302:            }
                    303:
                    304:        case ns_t_x25:
                    305:                T(len = charstr(rdata, edata, &buf, &buflen));
                    306:                if (len == 0)
                    307:                        goto formerr;
                    308:                rdata += len;
                    309:                break;
                    310:
                    311:        case ns_t_txt:
1.8.14.1! riz       312:        case ns_t_spf:
1.1       christos  313:                while (rdata < edata) {
                    314:                        T(len = charstr(rdata, edata, &buf, &buflen));
                    315:                        if (len == 0)
                    316:                                goto formerr;
                    317:                        rdata += len;
                    318:                        if (rdata < edata)
1.2       christos  319:                                T(addstr(" ", (size_t)1, &buf, &buflen));
1.1       christos  320:                }
                    321:                break;
                    322:
                    323:        case ns_t_nsap: {
                    324:                char t[2+255*3];
                    325:
1.2       christos  326:                (void) inet_nsap_ntoa((int)rdlen, rdata, t);
1.1       christos  327:                T(addstr(t, strlen(t), &buf, &buflen));
                    328:                break;
                    329:            }
                    330:
                    331:        case ns_t_aaaa:
                    332:                if (rdlen != (size_t)NS_IN6ADDRSZ)
                    333:                        goto formerr;
                    334:                (void) inet_ntop(AF_INET6, rdata, buf, buflen);
                    335:                addlen(strlen(buf), &buf, &buflen);
                    336:                break;
                    337:
                    338:        case ns_t_loc: {
                    339:                char t[255];
                    340:
                    341:                /* XXX protocol format checking? */
                    342:                (void) loc_ntoa(rdata, t);
                    343:                T(addstr(t, strlen(t), &buf, &buflen));
                    344:                break;
                    345:            }
                    346:
                    347:        case ns_t_naptr: {
                    348:                u_int order, preference;
                    349:                char t[50];
                    350:
                    351:                if (rdlen < 2U*NS_INT16SZ)
                    352:                        goto formerr;
                    353:
                    354:                /* Order, Precedence. */
                    355:                order = ns_get16(rdata);        rdata += NS_INT16SZ;
                    356:                preference = ns_get16(rdata);   rdata += NS_INT16SZ;
                    357:                len = SPRINTF((t, "%u %u ", order, preference));
1.2       christos  358:                T(addstr(t, (size_t)len, &buf, &buflen));
1.1       christos  359:
                    360:                /* Flags. */
                    361:                T(len = charstr(rdata, edata, &buf, &buflen));
                    362:                if (len == 0)
                    363:                        goto formerr;
                    364:                rdata += len;
1.2       christos  365:                T(addstr(" ", (size_t)1, &buf, &buflen));
1.1       christos  366:
                    367:                /* Service. */
                    368:                T(len = charstr(rdata, edata, &buf, &buflen));
                    369:                if (len == 0)
                    370:                        goto formerr;
                    371:                rdata += len;
1.2       christos  372:                T(addstr(" ", (size_t)1, &buf, &buflen));
1.1       christos  373:
                    374:                /* Regexp. */
                    375:                T(len = charstr(rdata, edata, &buf, &buflen));
                    376:                if (len < 0)
                    377:                        return (-1);
                    378:                if (len == 0)
                    379:                        goto formerr;
                    380:                rdata += len;
1.2       christos  381:                T(addstr(" ", (size_t)1, &buf, &buflen));
1.1       christos  382:
                    383:                /* Server. */
                    384:                T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
                    385:                break;
                    386:            }
                    387:
                    388:        case ns_t_srv: {
                    389:                u_int priority, weight, port;
                    390:                char t[50];
                    391:
                    392:                if (rdlen < 3U*NS_INT16SZ)
                    393:                        goto formerr;
                    394:
                    395:                /* Priority, Weight, Port. */
                    396:                priority = ns_get16(rdata);  rdata += NS_INT16SZ;
                    397:                weight   = ns_get16(rdata);  rdata += NS_INT16SZ;
                    398:                port     = ns_get16(rdata);  rdata += NS_INT16SZ;
                    399:                len = SPRINTF((t, "%u %u %u ", priority, weight, port));
1.2       christos  400:                T(addstr(t, (size_t)len, &buf, &buflen));
1.1       christos  401:
                    402:                /* Server. */
                    403:                T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
                    404:                break;
                    405:            }
                    406:
                    407:        case ns_t_minfo:
                    408:        case ns_t_rp:
                    409:                /* Name1. */
                    410:                T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
1.2       christos  411:                T(addstr(" ", (size_t)1, &buf, &buflen));
1.1       christos  412:
                    413:                /* Name2. */
                    414:                T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
                    415:
                    416:                break;
                    417:
                    418:        case ns_t_wks: {
                    419:                int n, lcnt;
                    420:
                    421:                if (rdlen < 1U + NS_INT32SZ)
                    422:                        goto formerr;
                    423:
                    424:                /* Address. */
                    425:                (void) inet_ntop(AF_INET, rdata, buf, buflen);
                    426:                addlen(strlen(buf), &buf, &buflen);
                    427:                rdata += NS_INADDRSZ;
                    428:
                    429:                /* Protocol. */
                    430:                len = SPRINTF((tmp, " %u ( ", *rdata));
1.2       christos  431:                T(addstr(tmp, (size_t)len, &buf, &buflen));
1.1       christos  432:                rdata += NS_INT8SZ;
                    433:
                    434:                /* Bit map. */
                    435:                n = 0;
                    436:                lcnt = 0;
                    437:                while (rdata < edata) {
                    438:                        u_int c = *rdata++;
                    439:                        do {
                    440:                                if (c & 0200) {
                    441:                                        if (lcnt == 0) {
1.2       christos  442:                                                T(addstr("\n\t\t\t\t", (size_t)5,
1.1       christos  443:                                                         &buf, &buflen));
                    444:                                                lcnt = 10;
                    445:                                                spaced = 0;
                    446:                                        }
                    447:                                        len = SPRINTF((tmp, "%d ", n));
1.2       christos  448:                                        T(addstr(tmp, (size_t)len, &buf, &buflen));
1.1       christos  449:                                        lcnt--;
                    450:                                }
                    451:                                c <<= 1;
                    452:                        } while (++n & 07);
                    453:                }
1.2       christos  454:                T(addstr(")", (size_t)1, &buf, &buflen));
1.1       christos  455:
                    456:                break;
                    457:            }
                    458:
1.8.14.1! riz       459:        case ns_t_key:
        !           460:        case ns_t_dnskey: {
1.1       christos  461:                char base64_key[NS_MD5RSA_MAX_BASE64];
                    462:                u_int keyflags, protocol, algorithm, key_id;
                    463:                const char *leader;
                    464:                int n;
                    465:
                    466:                if (rdlen < 0U + NS_INT16SZ + NS_INT8SZ + NS_INT8SZ)
                    467:                        goto formerr;
                    468:
                    469:                /* Key flags, Protocol, Algorithm. */
1.3       christos  470: #ifndef _LIBC
1.1       christos  471:                key_id = dst_s_dns_key_id(rdata, edata-rdata);
1.3       christos  472: #else
                    473:                key_id = 0;
                    474: #endif
1.1       christos  475:                keyflags = ns_get16(rdata);  rdata += NS_INT16SZ;
                    476:                protocol = *rdata++;
                    477:                algorithm = *rdata++;
                    478:                len = SPRINTF((tmp, "0x%04x %u %u",
                    479:                               keyflags, protocol, algorithm));
1.2       christos  480:                T(addstr(tmp, (size_t)len, &buf, &buflen));
1.1       christos  481:
                    482:                /* Public key data. */
1.2       christos  483:                len = b64_ntop(rdata, (size_t)(edata - rdata),
1.1       christos  484:                               base64_key, sizeof base64_key);
                    485:                if (len < 0)
                    486:                        goto formerr;
                    487:                if (len > 15) {
1.2       christos  488:                        T(addstr(" (", (size_t)2, &buf, &buflen));
1.1       christos  489:                        leader = "\n\t\t";
                    490:                        spaced = 0;
                    491:                } else
                    492:                        leader = " ";
                    493:                for (n = 0; n < len; n += 48) {
                    494:                        T(addstr(leader, strlen(leader), &buf, &buflen));
1.2       christos  495:                        T(addstr(base64_key + n, (size_t)MIN(len - n, 48),
1.1       christos  496:                                 &buf, &buflen));
                    497:                }
                    498:                if (len > 15)
1.2       christos  499:                        T(addstr(" )", (size_t)2, &buf, &buflen));
1.1       christos  500:                n = SPRINTF((tmp, " ; key_tag= %u", key_id));
1.2       christos  501:                T(addstr(tmp, (size_t)n, &buf, &buflen));
1.1       christos  502:
                    503:                break;
                    504:            }
                    505:
1.8.14.1! riz       506:        case ns_t_sig:
        !           507:        case ns_t_rrsig: {
1.1       christos  508:                char base64_key[NS_MD5RSA_MAX_BASE64];
1.2       christos  509:                u_int typ, algorithm, labels, footprint;
1.1       christos  510:                const char *leader;
                    511:                u_long t;
                    512:                int n;
                    513:
                    514:                if (rdlen < 22U)
                    515:                        goto formerr;
                    516:
                    517:                /* Type covered, Algorithm, Label count, Original TTL. */
1.2       christos  518:                typ = ns_get16(rdata);  rdata += NS_INT16SZ;
1.1       christos  519:                algorithm = *rdata++;
                    520:                labels = *rdata++;
                    521:                t = ns_get32(rdata);  rdata += NS_INT32SZ;
                    522:                len = SPRINTF((tmp, "%s %d %d %lu ",
1.2       christos  523:                               p_type((int)typ), algorithm, labels, t));
                    524:                T(addstr(tmp, (size_t)len, &buf, &buflen));
1.1       christos  525:                if (labels > (u_int)dn_count_labels(name))
                    526:                        goto formerr;
                    527:
                    528:                /* Signature expiry. */
                    529:                t = ns_get32(rdata);  rdata += NS_INT32SZ;
                    530:                len = SPRINTF((tmp, "%s ", p_secstodate(t)));
1.2       christos  531:                T(addstr(tmp, (size_t)len, &buf, &buflen));
1.1       christos  532:
                    533:                /* Time signed. */
                    534:                t = ns_get32(rdata);  rdata += NS_INT32SZ;
                    535:                len = SPRINTF((tmp, "%s ", p_secstodate(t)));
1.2       christos  536:                T(addstr(tmp, (size_t)len, &buf, &buflen));
1.1       christos  537:
                    538:                /* Signature Footprint. */
                    539:                footprint = ns_get16(rdata);  rdata += NS_INT16SZ;
                    540:                len = SPRINTF((tmp, "%u ", footprint));
1.2       christos  541:                T(addstr(tmp, (size_t)len, &buf, &buflen));
1.1       christos  542:
                    543:                /* Signer's name. */
                    544:                T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
                    545:
                    546:                /* Signature. */
1.2       christos  547:                len = b64_ntop(rdata, (size_t)(edata - rdata),
1.1       christos  548:                               base64_key, sizeof base64_key);
                    549:                if (len > 15) {
1.2       christos  550:                        T(addstr(" (", (size_t)2, &buf, &buflen));
1.1       christos  551:                        leader = "\n\t\t";
                    552:                        spaced = 0;
                    553:                } else
                    554:                        leader = " ";
                    555:                if (len < 0)
                    556:                        goto formerr;
                    557:                for (n = 0; n < len; n += 48) {
                    558:                        T(addstr(leader, strlen(leader), &buf, &buflen));
1.2       christos  559:                        T(addstr(base64_key + n, (size_t)MIN(len - n, 48),
1.1       christos  560:                                 &buf, &buflen));
                    561:                }
                    562:                if (len > 15)
1.2       christos  563:                        T(addstr(" )", (size_t)2, &buf, &buflen));
1.1       christos  564:                break;
                    565:            }
                    566:
                    567:        case ns_t_nxt: {
                    568:                int n, c;
                    569:
                    570:                /* Next domain name. */
                    571:                T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
                    572:
                    573:                /* Type bit map. */
                    574:                n = edata - rdata;
                    575:                for (c = 0; c < n*8; c++)
                    576:                        if (NS_NXT_BIT_ISSET(c, rdata)) {
                    577:                                len = SPRINTF((tmp, " %s", p_type(c)));
1.2       christos  578:                                T(addstr(tmp, (size_t)len, &buf, &buflen));
1.1       christos  579:                        }
                    580:                break;
                    581:            }
                    582:
                    583:        case ns_t_cert: {
                    584:                u_int c_type, key_tag, alg;
                    585:                int n;
                    586:                unsigned int siz;
1.2       christos  587:                char base64_cert[8192], tmp1[40];
1.1       christos  588:                const char *leader;
                    589:
                    590:                c_type  = ns_get16(rdata); rdata += NS_INT16SZ;
                    591:                key_tag = ns_get16(rdata); rdata += NS_INT16SZ;
                    592:                alg = (u_int) *rdata++;
                    593:
1.2       christos  594:                len = SPRINTF((tmp1, "%d %d %d ", c_type, key_tag, alg));
                    595:                T(addstr(tmp1, (size_t)len, &buf, &buflen));
1.1       christos  596:                siz = (edata-rdata)*4/3 + 4; /* "+4" accounts for trailing \0 */
                    597:                if (siz > sizeof(base64_cert) * 3/4) {
                    598:                        const char *str = "record too long to print";
                    599:                        T(addstr(str, strlen(str), &buf, &buflen));
                    600:                }
                    601:                else {
1.2       christos  602:                        len = b64_ntop(rdata, (size_t)(edata-rdata),
                    603:                            base64_cert, siz);
1.1       christos  604:
                    605:                        if (len < 0)
                    606:                                goto formerr;
                    607:                        else if (len > 15) {
1.2       christos  608:                                T(addstr(" (", (size_t)2, &buf, &buflen));
1.1       christos  609:                                leader = "\n\t\t";
                    610:                                spaced = 0;
                    611:                        }
                    612:                        else
                    613:                                leader = " ";
                    614:
                    615:                        for (n = 0; n < len; n += 48) {
                    616:                                T(addstr(leader, strlen(leader),
                    617:                                         &buf, &buflen));
1.2       christos  618:                                T(addstr(base64_cert + n, (size_t)MIN(len - n, 48),
1.1       christos  619:                                         &buf, &buflen));
                    620:                        }
                    621:                        if (len > 15)
1.2       christos  622:                                T(addstr(" )", (size_t)2, &buf, &buflen));
1.1       christos  623:                }
                    624:                break;
                    625:            }
                    626:
                    627:        case ns_t_tkey: {
                    628:                /* KJD - need to complete this */
                    629:                u_long t;
                    630:                int mode, err, keysize;
                    631:
                    632:                /* Algorithm name. */
                    633:                T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
1.2       christos  634:                T(addstr(" ", (size_t)1, &buf, &buflen));
1.1       christos  635:
                    636:                /* Inception. */
                    637:                t = ns_get32(rdata);  rdata += NS_INT32SZ;
                    638:                len = SPRINTF((tmp, "%s ", p_secstodate(t)));
1.2       christos  639:                T(addstr(tmp, (size_t)len, &buf, &buflen));
1.1       christos  640:
                    641:                /* Experation. */
                    642:                t = ns_get32(rdata);  rdata += NS_INT32SZ;
                    643:                len = SPRINTF((tmp, "%s ", p_secstodate(t)));
1.2       christos  644:                T(addstr(tmp, (size_t)len, &buf, &buflen));
1.1       christos  645:
                    646:                /* Mode , Error, Key Size. */
                    647:                /* Priority, Weight, Port. */
                    648:                mode = ns_get16(rdata);  rdata += NS_INT16SZ;
                    649:                err  = ns_get16(rdata);  rdata += NS_INT16SZ;
                    650:                keysize  = ns_get16(rdata);  rdata += NS_INT16SZ;
                    651:                len = SPRINTF((tmp, "%u %u %u ", mode, err, keysize));
1.2       christos  652:                T(addstr(tmp, (size_t)len, &buf, &buflen));
1.1       christos  653:
                    654:                /* XXX need to dump key, print otherdata length & other data */
                    655:                break;
                    656:            }
                    657:
                    658:        case ns_t_tsig: {
                    659:                /* BEW - need to complete this */
                    660:                int n;
                    661:
                    662:                T(len = addname(msg, msglen, &rdata, origin, &buf, &buflen));
1.2       christos  663:                T(addstr(" ", (size_t)1, &buf, &buflen));
1.6       christos  664:                rdata += 8; /*%< time */
1.1       christos  665:                n = ns_get16(rdata); rdata += INT16SZ;
1.6       christos  666:                rdata += n; /*%< sig */
                    667:                n = ns_get16(rdata); rdata += INT16SZ; /*%< original id */
1.1       christos  668:                sprintf(buf, "%d", ns_get16(rdata));
                    669:                rdata += INT16SZ;
                    670:                addlen(strlen(buf), &buf, &buflen);
                    671:                break;
                    672:            }
                    673:
                    674:        case ns_t_a6: {
                    675:                struct in6_addr a;
                    676:                int pbyte, pbit;
                    677:
                    678:                /* prefix length */
                    679:                if (rdlen == 0U) goto formerr;
                    680:                len = SPRINTF((tmp, "%d ", *rdata));
1.2       christos  681:                T(addstr(tmp, (size_t)len, &buf, &buflen));
1.1       christos  682:                pbit = *rdata;
                    683:                if (pbit > 128) goto formerr;
                    684:                pbyte = (pbit & ~7) / 8;
                    685:                rdata++;
                    686:
                    687:                /* address suffix: provided only when prefix len != 128 */
                    688:                if (pbit < 128) {
                    689:                        if (rdata + pbyte >= edata) goto formerr;
                    690:                        memset(&a, 0, sizeof(a));
                    691:                        memcpy(&a.s6_addr[pbyte], rdata, sizeof(a) - pbyte);
                    692:                        (void) inet_ntop(AF_INET6, &a, buf, buflen);
                    693:                        addlen(strlen(buf), &buf, &buflen);
                    694:                        rdata += sizeof(a) - pbyte;
                    695:                }
                    696:
                    697:                /* prefix name: provided only when prefix len > 0 */
                    698:                if (pbit == 0)
                    699:                        break;
                    700:                if (rdata >= edata) goto formerr;
1.2       christos  701:                T(addstr(" ", (size_t)1, &buf, &buflen));
1.1       christos  702:                T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
                    703:
                    704:                break;
                    705:            }
                    706:
                    707:        case ns_t_opt: {
                    708:                len = SPRINTF((tmp, "%u bytes", class));
1.2       christos  709:                T(addstr(tmp, (size_t)len, &buf, &buflen));
1.1       christos  710:                break;
                    711:            }
                    712:
1.8.14.1! riz       713:        case ns_t_ds:
        !           714:        case ns_t_dlv:
        !           715:        case ns_t_sshfp: {
        !           716:                u_int t;
        !           717:
        !           718:                if (type == ns_t_ds || type == ns_t_dlv) {
        !           719:                        if (rdlen < 4U) goto formerr;
        !           720:                        t = ns_get16(rdata);
        !           721:                        rdata += NS_INT16SZ;
        !           722:                        len = SPRINTF((tmp, "%u ", t));
        !           723:                        T(addstr(tmp, (size_t)len, &buf, &buflen));
        !           724:                } else
        !           725:                        if (rdlen < 2U) goto formerr;
        !           726:
        !           727:                len = SPRINTF((tmp, "%u ", *rdata));
        !           728:                T(addstr(tmp, (size_t)len, &buf, &buflen));
        !           729:                rdata++;
        !           730:
        !           731:                len = SPRINTF((tmp, "%u ", *rdata));
        !           732:                T(addstr(tmp, (size_t)len, &buf, &buflen));
        !           733:                rdata++;
        !           734:
        !           735:                while (rdata < edata) {
        !           736:                        len = SPRINTF((tmp, "%02X", *rdata));
        !           737:                        T(addstr(tmp, (size_t)len, &buf, &buflen));
        !           738:                        rdata++;
        !           739:                }
        !           740:                break;
        !           741:            }
        !           742:
        !           743:        case ns_t_nsec3:
        !           744:        case ns_t_nsec3param: {
        !           745:                u_int t, w, l, j, k, c;
        !           746:
        !           747:                len = SPRINTF((tmp, "%u ", *rdata));
        !           748:                T(addstr(tmp, (size_t)len, &buf, &buflen));
        !           749:                rdata++;
        !           750:
        !           751:                len = SPRINTF((tmp, "%u ", *rdata));
        !           752:                T(addstr(tmp, (size_t)len, &buf, &buflen));
        !           753:                rdata++;
        !           754:
        !           755:                t = ns_get16(rdata);
        !           756:                rdata += NS_INT16SZ;
        !           757:                len = SPRINTF((tmp, "%u ", t));
        !           758:                T(addstr(tmp, (size_t)len, &buf, &buflen));
        !           759:
        !           760:                t = *rdata++;
        !           761:                if (t == 0) {
        !           762:                        T(addstr("-", 1, &buf, &buflen));
        !           763:                } else {
        !           764:                        while (t-- > 0) {
        !           765:                                len = SPRINTF((tmp, "%02X", *rdata));
        !           766:                                T(addstr(tmp, (size_t)len, &buf, &buflen));
        !           767:                                rdata++;
        !           768:                        }
        !           769:                }
        !           770:                if (type == ns_t_nsec3param)
        !           771:                        break;
        !           772:                T(addstr(" ", 1, &buf, &buflen));
        !           773:
        !           774:                t = *rdata++;
        !           775:                while (t > 0) {
        !           776:                        switch (t) {
        !           777:                        case 1:
        !           778:                                tmp[0] = base32hex[(((uint32_t)rdata[0]>>3)&0x1f)];
        !           779:                                tmp[1] = base32hex[(((uint32_t)rdata[0]<<2)&0x1c)];
        !           780:                                tmp[2] = tmp[3] = tmp[4] = '=';
        !           781:                                tmp[5] = tmp[6] = tmp[7] = '=';
        !           782:                                break;
        !           783:                        case 2:
        !           784:                                tmp[0] = base32hex[(((uint32_t)rdata[0]>>3)&0x1f)];
        !           785:                                tmp[1] = base32hex[(((uint32_t)rdata[0]<<2)&0x1c)|
        !           786:                                                   (((uint32_t)rdata[1]>>6)&0x03)];
        !           787:                                tmp[2] = base32hex[(((uint32_t)rdata[1]>>1)&0x1f)];
        !           788:                                tmp[3] = base32hex[(((uint32_t)rdata[1]<<4)&0x10)];
        !           789:                                tmp[4] = tmp[5] = tmp[6] = tmp[7] = '=';
        !           790:                                break;
        !           791:                        case 3:
        !           792:                                tmp[0] = base32hex[(((uint32_t)rdata[0]>>3)&0x1f)];
        !           793:                                tmp[1] = base32hex[(((uint32_t)rdata[0]<<2)&0x1c)|
        !           794:                                                   (((uint32_t)rdata[1]>>6)&0x03)];
        !           795:                                tmp[2] = base32hex[(((uint32_t)rdata[1]>>1)&0x1f)];
        !           796:                                tmp[3] = base32hex[(((uint32_t)rdata[1]<<4)&0x10)|
        !           797:                                                   (((uint32_t)rdata[2]>>4)&0x0f)];
        !           798:                                tmp[4] = base32hex[(((uint32_t)rdata[2]<<1)&0x1e)];
        !           799:                                tmp[5] = tmp[6] = tmp[7] = '=';
        !           800:                                break;
        !           801:                        case 4:
        !           802:                                tmp[0] = base32hex[(((uint32_t)rdata[0]>>3)&0x1f)];
        !           803:                                tmp[1] = base32hex[(((uint32_t)rdata[0]<<2)&0x1c)|
        !           804:                                                   (((uint32_t)rdata[1]>>6)&0x03)];
        !           805:                                tmp[2] = base32hex[(((uint32_t)rdata[1]>>1)&0x1f)];
        !           806:                                tmp[3] = base32hex[(((uint32_t)rdata[1]<<4)&0x10)|
        !           807:                                                   (((uint32_t)rdata[2]>>4)&0x0f)];
        !           808:                                tmp[4] = base32hex[(((uint32_t)rdata[2]<<1)&0x1e)|
        !           809:                                                   (((uint32_t)rdata[3]>>7)&0x01)];
        !           810:                                tmp[5] = base32hex[(((uint32_t)rdata[3]>>2)&0x1f)];
        !           811:                                tmp[6] = base32hex[((uint32_t)rdata[3]<<3)&0x18];
        !           812:                                tmp[7] = '=';
        !           813:                                break;
        !           814:                        default:
        !           815:                                tmp[0] = base32hex[(((uint32_t)rdata[0]>>3)&0x1f)];
        !           816:                                tmp[1] = base32hex[(((uint32_t)rdata[0]<<2)&0x1c)|
        !           817:                                                   (((uint32_t)rdata[1]>>6)&0x03)];
        !           818:                                tmp[2] = base32hex[(((uint32_t)rdata[1]>>1)&0x1f)];
        !           819:                                tmp[3] = base32hex[(((uint32_t)rdata[1]<<4)&0x10)|
        !           820:                                                   (((uint32_t)rdata[2]>>4)&0x0f)];
        !           821:                                tmp[4] = base32hex[(((uint32_t)rdata[2]<<1)&0x1e)|
        !           822:                                                   (((uint32_t)rdata[3]>>7)&0x01)];
        !           823:                                tmp[5] = base32hex[(((uint32_t)rdata[3]>>2)&0x1f)];
        !           824:                                tmp[6] = base32hex[(((uint32_t)rdata[3]<<3)&0x18)|
        !           825:                                                   (((uint32_t)rdata[4]>>5)&0x07)];
        !           826:                                tmp[7] = base32hex[(rdata[4]&0x1f)];
        !           827:                                break;
        !           828:                        }
        !           829:                        T(addstr(tmp, 8, &buf, &buflen));
        !           830:                        if (t >= 5) {
        !           831:                                rdata += 5;
        !           832:                                t -= 5;
        !           833:                        } else {
        !           834:                                rdata += t;
        !           835:                                t -= t;
        !           836:                        }
        !           837:                }
        !           838:
        !           839:                while (rdata < edata) {
        !           840:                        w = *rdata++;
        !           841:                        l = *rdata++;
        !           842:                        for (j = 0; j < l; j++) {
        !           843:                                if (rdata[j] == 0)
        !           844:                                        continue;
        !           845:                                for (k = 0; k < 8; k++) {
        !           846:                                        if ((rdata[j] & (0x80 >> k)) == 0)
        !           847:                                                continue;
        !           848:                                        c = w * 256 + j * 8 + k;
        !           849:                                        len = SPRINTF((tmp, " %s", p_type((ns_type)c)));
        !           850:                                        T(addstr(tmp, (size_t)len, &buf, &buflen));
        !           851:                                }
        !           852:                        }
        !           853:                        rdata += l;
        !           854:                }
        !           855:                break;
        !           856:            }
        !           857:
        !           858:        case ns_t_nsec: {
        !           859:                u_int w, l, j, k, c;
        !           860:
        !           861:                T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
        !           862:
        !           863:                while (rdata < edata) {
        !           864:                        w = *rdata++;
        !           865:                        l = *rdata++;
        !           866:                        for (j = 0; j < l; j++) {
        !           867:                                if (rdata[j] == 0)
        !           868:                                        continue;
        !           869:                                for (k = 0; k < 8; k++) {
        !           870:                                        if ((rdata[j] & (0x80 >> k)) == 0)
        !           871:                                                continue;
        !           872:                                        c = w * 256 + j * 8 + k;
        !           873:                                        len = SPRINTF((tmp, " %s", p_type((ns_type)c)));
        !           874:                                        T(addstr(tmp, (size_t)len, &buf, &buflen));
        !           875:                                }
        !           876:                        }
        !           877:                        rdata += l;
        !           878:                }
        !           879:                break;
        !           880:            }
        !           881:
        !           882:        case ns_t_dhcid: {
        !           883:                int n;
        !           884:                unsigned int siz;
        !           885:                char base64_dhcid[8192];
        !           886:                const char *leader;
        !           887:
        !           888:                siz = (edata-rdata)*4/3 + 4; /* "+4" accounts for trailing \0 */
        !           889:                if (siz > sizeof(base64_dhcid) * 3/4) {
        !           890:                        const char *str = "record too long to print";
        !           891:                        T(addstr(str, strlen(str), &buf, &buflen));
        !           892:                } else {
        !           893:                        len = b64_ntop(rdata, (size_t)(edata-rdata),
        !           894:                            base64_dhcid, siz);
        !           895:
        !           896:                        if (len < 0)
        !           897:                                goto formerr;
        !           898:
        !           899:                        else if (len > 15) {
        !           900:                                T(addstr(" (", 2, &buf, &buflen));
        !           901:                                leader = "\n\t\t";
        !           902:                                spaced = 0;
        !           903:                        }
        !           904:                        else
        !           905:                                leader = " ";
        !           906:
        !           907:                        for (n = 0; n < len; n += 48) {
        !           908:                                T(addstr(leader, strlen(leader),
        !           909:                                         &buf, &buflen));
        !           910:                                T(addstr(base64_dhcid + n,
        !           911:                                    (size_t)MIN(len - n, 48), &buf, &buflen));
        !           912:                        }
        !           913:                        if (len > 15)
        !           914:                                T(addstr(" )", 2, &buf, &buflen));
        !           915:                }
        !           916:                break;
        !           917:        }
        !           918:
        !           919:        case ns_t_ipseckey: {
        !           920:                int n;
        !           921:                unsigned int siz;
        !           922:                char base64_key[8192];
        !           923:                const char *leader;
        !           924:
        !           925:                if (rdlen < 2)
        !           926:                        goto formerr;
        !           927:
        !           928:                switch (rdata[1]) {
        !           929:                case 0:
        !           930:                case 3:
        !           931:                        if (rdlen < 3)
        !           932:                                goto formerr;
        !           933:                        break;
        !           934:                case 1:
        !           935:                        if (rdlen < 7)
        !           936:                                goto formerr;
        !           937:                        break;
        !           938:                case 2:
        !           939:                        if (rdlen < 19)
        !           940:                                goto formerr;
        !           941:                        break;
        !           942:                default:
        !           943:                        comment = "unknown IPSECKEY gateway type";
        !           944:                        goto hexify;
        !           945:                }
        !           946:
        !           947:                len = SPRINTF((tmp, "%u ", *rdata));
        !           948:                T(addstr(tmp, (size_t)len, &buf, &buflen));
        !           949:                rdata++;
        !           950:
        !           951:                len = SPRINTF((tmp, "%u ", *rdata));
        !           952:                T(addstr(tmp, (size_t)len, &buf, &buflen));
        !           953:                rdata++;
        !           954:
        !           955:                len = SPRINTF((tmp, "%u ", *rdata));
        !           956:                T(addstr(tmp, (size_t)len, &buf, &buflen));
        !           957:                rdata++;
        !           958:
        !           959:                switch (rdata[-2]) {
        !           960:                case 0:
        !           961:                        T(addstr(".", 1, &buf, &buflen));
        !           962:                        break;
        !           963:                case 1:
        !           964:                        (void) inet_ntop(AF_INET, rdata, buf, buflen);
        !           965:                        addlen(strlen(buf), &buf, &buflen);
        !           966:                        rdata += 4;
        !           967:                        break;
        !           968:                case 2:
        !           969:                        (void) inet_ntop(AF_INET6, rdata, buf, buflen);
        !           970:                        addlen(strlen(buf), &buf, &buflen);
        !           971:                        rdata += 16;
        !           972:                        break;
        !           973:                case 3:
        !           974:                        T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
        !           975:                        break;
        !           976:                }
        !           977:
        !           978:                if (rdata >= edata)
        !           979:                        break;
        !           980:
        !           981:                siz = (edata-rdata)*4/3 + 4; /* "+4" accounts for trailing \0 */
        !           982:                if (siz > sizeof(base64_key) * 3/4) {
        !           983:                        const char *str = "record too long to print";
        !           984:                        T(addstr(str, strlen(str), &buf, &buflen));
        !           985:                } else {
        !           986:                        len = b64_ntop(rdata, (size_t)(edata-rdata),
        !           987:                            base64_key, siz);
        !           988:
        !           989:                        if (len < 0)
        !           990:                                goto formerr;
        !           991:
        !           992:                        else if (len > 15) {
        !           993:                                T(addstr(" (", 2, &buf, &buflen));
        !           994:                                leader = "\n\t\t";
        !           995:                                spaced = 0;
        !           996:                        }
        !           997:                        else
        !           998:                                leader = " ";
        !           999:
        !          1000:                        for (n = 0; n < len; n += 48) {
        !          1001:                                T(addstr(leader, strlen(leader),
        !          1002:                                         &buf, &buflen));
        !          1003:                                T(addstr(base64_key + n,
        !          1004:                                    (size_t)MIN(len - n, 48), &buf, &buflen));
        !          1005:                        }
        !          1006:                        if (len > 15)
        !          1007:                                T(addstr(" )", 2, &buf, &buflen));
        !          1008:                }
        !          1009:                break;
        !          1010:        }
        !          1011:
        !          1012:        case ns_t_hip: {
        !          1013:                unsigned int i, hip_len, algorithm, key_len;
        !          1014:                char base64_key[NS_MD5RSA_MAX_BASE64];
        !          1015:                unsigned int siz;
        !          1016:                const char *leader = "\n\t\t\t\t\t";
        !          1017:
        !          1018:                hip_len = *rdata++;
        !          1019:                algorithm = *rdata++;
        !          1020:                key_len = ns_get16(rdata);
        !          1021:                rdata += NS_INT16SZ;
        !          1022:
        !          1023:                siz = key_len*4/3 + 4; /* "+4" accounts for trailing \0 */
        !          1024:                if (siz > sizeof(base64_key) * 3/4) {
        !          1025:                        const char *str = "record too long to print";
        !          1026:                        T(addstr(str, strlen(str), &buf, &buflen));
        !          1027:                } else {
        !          1028:                        len = sprintf(tmp, "( %u ", algorithm);
        !          1029:                        T(addstr(tmp, (size_t)len, &buf, &buflen));
        !          1030:
        !          1031:                        for (i = 0; i < hip_len; i++) {
        !          1032:                                len = sprintf(tmp, "%02X", *rdata);
        !          1033:                                T(addstr(tmp, (size_t)len, &buf, &buflen));
        !          1034:                                rdata++;
        !          1035:                        }
        !          1036:                        T(addstr(leader, strlen(leader), &buf, &buflen));
        !          1037:
        !          1038:                        len = b64_ntop(rdata, key_len, base64_key, siz);
        !          1039:                        if (len < 0)
        !          1040:                                goto formerr;
        !          1041:
        !          1042:                        T(addstr(base64_key, (size_t)len, &buf, &buflen));
        !          1043:
        !          1044:                        rdata += key_len;
        !          1045:                        while (rdata < edata) {
        !          1046:                                T(addstr(leader, strlen(leader), &buf, &buflen));
        !          1047:                                T(addname(msg, msglen, &rdata, origin,
        !          1048:                                          &buf, &buflen));
        !          1049:                        }
        !          1050:                        T(addstr(" )", 2, &buf, &buflen));
        !          1051:                }
        !          1052:                break;
        !          1053:        }
        !          1054:
1.1       christos 1055:        default:
                   1056:                comment = "unknown RR type";
                   1057:                goto hexify;
                   1058:        }
                   1059:        return (buf - obuf);
                   1060:  formerr:
                   1061:        comment = "RR format error";
                   1062:  hexify: {
                   1063:        int n, m;
                   1064:        char *p;
                   1065:
1.6       christos 1066:        len = SPRINTF((tmp, "\\# %u%s\t; %s", (unsigned)(edata - rdata),
                   1067:                       rdlen != 0U ? " (" : "", comment));
1.2       christos 1068:        T(addstr(tmp, (size_t)len, &buf, &buflen));
1.1       christos 1069:        while (rdata < edata) {
                   1070:                p = tmp;
                   1071:                p += SPRINTF((p, "\n\t"));
                   1072:                spaced = 0;
                   1073:                n = MIN(16, edata - rdata);
                   1074:                for (m = 0; m < n; m++)
                   1075:                        p += SPRINTF((p, "%02x ", rdata[m]));
1.2       christos 1076:                T(addstr(tmp, (size_t)(p - tmp), &buf, &buflen));
1.1       christos 1077:                if (n < 16) {
1.2       christos 1078:                        T(addstr(")", (size_t)1, &buf, &buflen));
                   1079:                        T(addtab((size_t)(p - tmp + 1), (size_t)48, spaced, &buf, &buflen));
1.1       christos 1080:                }
                   1081:                p = tmp;
                   1082:                p += SPRINTF((p, "; "));
                   1083:                for (m = 0; m < n; m++)
                   1084:                        *p++ = (isascii(rdata[m]) && isprint(rdata[m]))
                   1085:                                ? rdata[m]
                   1086:                                : '.';
1.2       christos 1087:                T(addstr(tmp, (size_t)(p - tmp), &buf, &buflen));
1.1       christos 1088:                rdata += n;
                   1089:        }
                   1090:        return (buf - obuf);
                   1091:     }
                   1092: }
                   1093:
                   1094: /* Private. */
                   1095:
1.6       christos 1096: /*%
1.1       christos 1097:  * size_t
                   1098:  * prune_origin(name, origin)
                   1099:  *     Find out if the name is at or under the current origin.
                   1100:  * return:
                   1101:  *     Number of characters in name before start of origin,
                   1102:  *     or length of name if origin does not match.
                   1103:  * notes:
                   1104:  *     This function should share code with samedomain().
                   1105:  */
                   1106: static size_t
                   1107: prune_origin(const char *name, const char *origin) {
                   1108:        const char *oname = name;
                   1109:
                   1110:        while (*name != '\0') {
                   1111:                if (origin != NULL && ns_samename(name, origin) == 1)
                   1112:                        return (name - oname - (name > oname));
                   1113:                while (*name != '\0') {
                   1114:                        if (*name == '\\') {
                   1115:                                name++;
                   1116:                                /* XXX need to handle \nnn form. */
                   1117:                                if (*name == '\0')
                   1118:                                        break;
                   1119:                        } else if (*name == '.') {
                   1120:                                name++;
                   1121:                                break;
                   1122:                        }
                   1123:                        name++;
                   1124:                }
                   1125:        }
                   1126:        return (name - oname);
                   1127: }
                   1128:
1.6       christos 1129: /*%
1.1       christos 1130:  * int
                   1131:  * charstr(rdata, edata, buf, buflen)
                   1132:  *     Format a <character-string> into the presentation buffer.
                   1133:  * return:
                   1134:  *     Number of rdata octets consumed
                   1135:  *     0 for protocol format error
                   1136:  *     -1 for output buffer error
                   1137:  * side effects:
                   1138:  *     buffer is advanced on success.
                   1139:  */
                   1140: static int
                   1141: charstr(const u_char *rdata, const u_char *edata, char **buf, size_t *buflen) {
                   1142:        const u_char *odata = rdata;
                   1143:        size_t save_buflen = *buflen;
                   1144:        char *save_buf = *buf;
                   1145:
1.2       christos 1146:        if (addstr("\"", (size_t)1, buf, buflen) < 0)
1.1       christos 1147:                goto enospc;
                   1148:        if (rdata < edata) {
                   1149:                int n = *rdata;
                   1150:
                   1151:                if (rdata + 1 + n <= edata) {
                   1152:                        rdata++;
                   1153:                        while (n-- > 0) {
                   1154:                                if (strchr("\n\"\\", *rdata) != NULL)
1.2       christos 1155:                                        if (addstr("\\", (size_t)1, buf, buflen) < 0)
1.1       christos 1156:                                                goto enospc;
1.2       christos 1157:                                if (addstr((const char *)rdata, (size_t)1,
1.1       christos 1158:                                           buf, buflen) < 0)
                   1159:                                        goto enospc;
                   1160:                                rdata++;
                   1161:                        }
                   1162:                }
                   1163:        }
1.2       christos 1164:        if (addstr("\"", (size_t)1, buf, buflen) < 0)
1.1       christos 1165:                goto enospc;
                   1166:        return (rdata - odata);
                   1167:  enospc:
                   1168:        errno = ENOSPC;
                   1169:        *buf = save_buf;
                   1170:        *buflen = save_buflen;
                   1171:        return (-1);
                   1172: }
                   1173:
                   1174: static int
                   1175: addname(const u_char *msg, size_t msglen,
                   1176:        const u_char **pp, const char *origin,
                   1177:        char **buf, size_t *buflen)
                   1178: {
                   1179:        size_t newlen, save_buflen = *buflen;
                   1180:        char *save_buf = *buf;
                   1181:        int n;
                   1182:
1.2       christos 1183:        n = dn_expand(msg, msg + msglen, *pp, *buf, (int)*buflen);
1.1       christos 1184:        if (n < 0)
1.6       christos 1185:                goto enospc;    /*%< Guess. */
1.1       christos 1186:        newlen = prune_origin(*buf, origin);
                   1187:        if (**buf == '\0') {
                   1188:                goto root;
                   1189:        } else if (newlen == 0U) {
                   1190:                /* Use "@" instead of name. */
                   1191:                if (newlen + 2 > *buflen)
                   1192:                        goto enospc;        /* No room for "@\0". */
                   1193:                (*buf)[newlen++] = '@';
                   1194:                (*buf)[newlen] = '\0';
                   1195:        } else {
                   1196:                if (((origin == NULL || origin[0] == '\0') ||
                   1197:                    (origin[0] != '.' && origin[1] != '\0' &&
                   1198:                    (*buf)[newlen] == '\0')) && (*buf)[newlen - 1] != '.') {
                   1199:                        /* No trailing dot. */
                   1200:  root:
                   1201:                        if (newlen + 2 > *buflen)
                   1202:                                goto enospc;    /* No room for ".\0". */
                   1203:                        (*buf)[newlen++] = '.';
                   1204:                        (*buf)[newlen] = '\0';
                   1205:                }
                   1206:        }
                   1207:        *pp += n;
                   1208:        addlen(newlen, buf, buflen);
                   1209:        **buf = '\0';
                   1210:        return (newlen);
                   1211:  enospc:
                   1212:        errno = ENOSPC;
                   1213:        *buf = save_buf;
                   1214:        *buflen = save_buflen;
                   1215:        return (-1);
                   1216: }
                   1217:
                   1218: static void
                   1219: addlen(size_t len, char **buf, size_t *buflen) {
                   1220:        INSIST(len <= *buflen);
                   1221:        *buf += len;
                   1222:        *buflen -= len;
                   1223: }
                   1224:
                   1225: static int
                   1226: addstr(const char *src, size_t len, char **buf, size_t *buflen) {
                   1227:        if (len >= *buflen) {
                   1228:                errno = ENOSPC;
                   1229:                return (-1);
                   1230:        }
                   1231:        memcpy(*buf, src, len);
                   1232:        addlen(len, buf, buflen);
                   1233:        **buf = '\0';
                   1234:        return (0);
                   1235: }
                   1236:
                   1237: static int
                   1238: addtab(size_t len, size_t target, int spaced, char **buf, size_t *buflen) {
                   1239:        size_t save_buflen = *buflen;
                   1240:        char *save_buf = *buf;
                   1241:        int t;
                   1242:
                   1243:        if (spaced || len >= target - 1) {
1.2       christos 1244:                T(addstr("  ", (size_t)2, buf, buflen));
1.1       christos 1245:                spaced = 1;
                   1246:        } else {
                   1247:                for (t = (target - len - 1) / 8; t >= 0; t--)
1.2       christos 1248:                        if (addstr("\t", (size_t)1, buf, buflen) < 0) {
1.1       christos 1249:                                *buflen = save_buflen;
                   1250:                                *buf = save_buf;
                   1251:                                return (-1);
                   1252:                        }
                   1253:                spaced = 0;
                   1254:        }
                   1255:        return (spaced);
                   1256: }
1.6       christos 1257:
                   1258: /*! \file */

CVSweb <webmaster@jp.NetBSD.org>