[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

1.8     ! christos    1: /*     $NetBSD: ns_print.c,v 1.7 2007/03/30 20:23:03 ghen 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     ! christos   23: static const char rcsid[] = "Id: ns_print.c,v 1.10 2005/04/27 04:56:40 sra Exp";
1.2       christos   24: #else
1.8     ! christos   25: __RCSID("$NetBSD: ns_print.c,v 1.7 2007/03/30 20:23:03 ghen 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:
                     77: /* Public. */
                     78:
1.6       christos   79: /*%
1.1       christos   80:  *     Convert an RR to presentation format.
1.6       christos   81:  *
1.1       christos   82:  * return:
1.6       christos   83:  *\li  Number of characters written to buf, or -1 (check errno).
1.1       christos   84:  */
                     85: int
                     86: ns_sprintrr(const ns_msg *handle, const ns_rr *rr,
                     87:            const char *name_ctx, const char *origin,
                     88:            char *buf, size_t buflen)
                     89: {
                     90:        int n;
                     91:
                     92:        n = ns_sprintrrf(ns_msg_base(*handle), ns_msg_size(*handle),
                     93:                         ns_rr_name(*rr), ns_rr_class(*rr), ns_rr_type(*rr),
                     94:                         ns_rr_ttl(*rr), ns_rr_rdata(*rr), ns_rr_rdlen(*rr),
                     95:                         name_ctx, origin, buf, buflen);
                     96:        return (n);
                     97: }
                     98:
1.6       christos   99: /*%
1.1       christos  100:  *     Convert the fields of an RR into presentation format.
1.6       christos  101:  *
1.1       christos  102:  * return:
1.6       christos  103:  *\li  Number of characters written to buf, or -1 (check errno).
1.1       christos  104:  */
                    105: int
                    106: ns_sprintrrf(const u_char *msg, size_t msglen,
                    107:            const char *name, ns_class class, ns_type type,
                    108:            u_long ttl, const u_char *rdata, size_t rdlen,
                    109:            const char *name_ctx, const char *origin,
                    110:            char *buf, size_t buflen)
                    111: {
                    112:        const char *obuf = buf;
                    113:        const u_char *edata = rdata + rdlen;
                    114:        int spaced = 0;
                    115:
                    116:        const char *comment;
                    117:        char tmp[100];
                    118:        int len, x;
                    119:
                    120:        /*
                    121:         * Owner.
                    122:         */
                    123:        if (name_ctx != NULL && ns_samename(name_ctx, name) == 1) {
1.2       christos  124:                T(addstr("\t\t\t", (size_t)3, &buf, &buflen));
1.1       christos  125:        } else {
                    126:                len = prune_origin(name, origin);
                    127:                if (*name == '\0') {
                    128:                        goto root;
                    129:                } else if (len == 0) {
1.2       christos  130:                        T(addstr("@\t\t\t", (size_t)4, &buf, &buflen));
1.1       christos  131:                } else {
1.2       christos  132:                        T(addstr(name, (size_t)len, &buf, &buflen));
1.1       christos  133:                        /* Origin not used or not root, and no trailing dot? */
                    134:                        if (((origin == NULL || origin[0] == '\0') ||
                    135:                            (origin[0] != '.' && origin[1] != '\0' &&
                    136:                            name[len] == '\0')) && name[len - 1] != '.') {
                    137:  root:
1.2       christos  138:                                T(addstr(".", (size_t)1, &buf, &buflen));
1.1       christos  139:                                len++;
                    140:                        }
1.2       christos  141:                        T(spaced = addtab((size_t)len, 24, spaced, &buf, &buflen));
1.1       christos  142:                }
                    143:        }
                    144:
                    145:        /*
                    146:         * TTL, Class, Type.
                    147:         */
                    148:        T(x = ns_format_ttl(ttl, buf, buflen));
1.2       christos  149:        addlen((size_t)x, &buf, &buflen);
1.1       christos  150:        len = SPRINTF((tmp, " %s %s", p_class(class), p_type(type)));
1.2       christos  151:        T(addstr(tmp, (size_t)len, &buf, &buflen));
                    152:        T(spaced = addtab((size_t)(x + len), (size_t)16, spaced, &buf, &buflen));
1.1       christos  153:
                    154:        /*
                    155:         * RData.
                    156:         */
                    157:        switch (type) {
                    158:        case ns_t_a:
                    159:                if (rdlen != (size_t)NS_INADDRSZ)
                    160:                        goto formerr;
                    161:                (void) inet_ntop(AF_INET, rdata, buf, buflen);
                    162:                addlen(strlen(buf), &buf, &buflen);
                    163:                break;
                    164:
                    165:        case ns_t_cname:
                    166:        case ns_t_mb:
                    167:        case ns_t_mg:
                    168:        case ns_t_mr:
                    169:        case ns_t_ns:
                    170:        case ns_t_ptr:
                    171:        case ns_t_dname:
                    172:                T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
                    173:                break;
                    174:
                    175:        case ns_t_hinfo:
                    176:        case ns_t_isdn:
                    177:                /* First word. */
                    178:                T(len = charstr(rdata, edata, &buf, &buflen));
                    179:                if (len == 0)
                    180:                        goto formerr;
                    181:                rdata += len;
1.2       christos  182:                T(addstr(" ", (size_t)1, &buf, &buflen));
1.1       christos  183:
                    184:
                    185:                /* Second word, optional in ISDN records. */
                    186:                if (type == ns_t_isdn && rdata == edata)
                    187:                        break;
                    188:
                    189:                T(len = charstr(rdata, edata, &buf, &buflen));
                    190:                if (len == 0)
                    191:                        goto formerr;
                    192:                rdata += len;
                    193:                break;
                    194:
                    195:        case ns_t_soa: {
                    196:                u_long t;
                    197:
                    198:                /* Server name. */
                    199:                T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
1.2       christos  200:                T(addstr(" ", (size_t)1, &buf, &buflen));
1.1       christos  201:
                    202:                /* Administrator name. */
                    203:                T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
1.2       christos  204:                T(addstr(" (\n", (size_t)3, &buf, &buflen));
1.1       christos  205:                spaced = 0;
                    206:
                    207:                if ((edata - rdata) != 5*NS_INT32SZ)
                    208:                        goto formerr;
                    209:
                    210:                /* Serial number. */
                    211:                t = ns_get32(rdata);  rdata += NS_INT32SZ;
1.2       christos  212:                T(addstr("\t\t\t\t\t", (size_t)5, &buf, &buflen));
1.1       christos  213:                len = SPRINTF((tmp, "%lu", t));
1.2       christos  214:                T(addstr(tmp, (size_t)len, &buf, &buflen));
                    215:                T(spaced = addtab((size_t)len, (size_t)16, spaced, &buf, &buflen));
                    216:                T(addstr("; serial\n", (size_t)9, &buf, &buflen));
1.1       christos  217:                spaced = 0;
                    218:
                    219:                /* Refresh interval. */
                    220:                t = ns_get32(rdata);  rdata += NS_INT32SZ;
1.2       christos  221:                T(addstr("\t\t\t\t\t", (size_t)5, &buf, &buflen));
1.1       christos  222:                T(len = ns_format_ttl(t, buf, buflen));
1.2       christos  223:                addlen((size_t)len, &buf, &buflen);
                    224:                T(spaced = addtab((size_t)len, (size_t)16, spaced, &buf, &buflen));
                    225:                T(addstr("; refresh\n", (size_t)10, &buf, &buflen));
1.1       christos  226:                spaced = 0;
                    227:
                    228:                /* Retry interval. */
                    229:                t = ns_get32(rdata);  rdata += NS_INT32SZ;
1.2       christos  230:                T(addstr("\t\t\t\t\t", (size_t)5, &buf, &buflen));
1.1       christos  231:                T(len = ns_format_ttl(t, buf, buflen));
1.2       christos  232:                addlen((size_t)len, &buf, &buflen);
                    233:                T(spaced = addtab((size_t)len, (size_t)16, spaced, &buf, &buflen));
                    234:                T(addstr("; retry\n", (size_t)8, &buf, &buflen));
1.1       christos  235:                spaced = 0;
                    236:
                    237:                /* Expiry. */
                    238:                t = ns_get32(rdata);  rdata += NS_INT32SZ;
1.2       christos  239:                T(addstr("\t\t\t\t\t", (size_t)5, &buf, &buflen));
1.1       christos  240:                T(len = ns_format_ttl(t, buf, buflen));
1.2       christos  241:                addlen((size_t)len, &buf, &buflen);
                    242:                T(spaced = addtab((size_t)len, (size_t)16, spaced, &buf, &buflen));
                    243:                T(addstr("; expiry\n", (size_t)9, &buf, &buflen));
1.1       christos  244:                spaced = 0;
                    245:
                    246:                /* Minimum TTL. */
                    247:                t = ns_get32(rdata);  rdata += NS_INT32SZ;
1.2       christos  248:                T(addstr("\t\t\t\t\t", (size_t)5, &buf, &buflen));
1.1       christos  249:                T(len = ns_format_ttl(t, buf, buflen));
1.2       christos  250:                addlen((size_t)len, &buf, &buflen);
                    251:                T(addstr(" )", (size_t)2, &buf, &buflen));
                    252:                T(spaced = addtab((size_t)len, (size_t)16, spaced, &buf, &buflen));
                    253:                T(addstr("; minimum\n", (size_t)10, &buf, &buflen));
1.1       christos  254:
                    255:                break;
                    256:            }
                    257:
                    258:        case ns_t_mx:
                    259:        case ns_t_afsdb:
                    260:        case ns_t_rt: {
                    261:                u_int t;
                    262:
                    263:                if (rdlen < (size_t)NS_INT16SZ)
                    264:                        goto formerr;
                    265:
                    266:                /* Priority. */
                    267:                t = ns_get16(rdata);
                    268:                rdata += NS_INT16SZ;
                    269:                len = SPRINTF((tmp, "%u ", t));
1.2       christos  270:                T(addstr(tmp, (size_t)len, &buf, &buflen));
1.1       christos  271:
                    272:                /* Target. */
                    273:                T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
                    274:
                    275:                break;
                    276:            }
                    277:
                    278:        case ns_t_px: {
                    279:                u_int t;
                    280:
                    281:                if (rdlen < (size_t)NS_INT16SZ)
                    282:                        goto formerr;
                    283:
                    284:                /* Priority. */
                    285:                t = ns_get16(rdata);
                    286:                rdata += NS_INT16SZ;
                    287:                len = SPRINTF((tmp, "%u ", t));
1.2       christos  288:                T(addstr(tmp, (size_t)len, &buf, &buflen));
1.1       christos  289:
                    290:                /* Name1. */
                    291:                T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
1.2       christos  292:                T(addstr(" ", (size_t)1, &buf, &buflen));
1.1       christos  293:
                    294:                /* Name2. */
                    295:                T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
                    296:
                    297:                break;
                    298:            }
                    299:
                    300:        case ns_t_x25:
                    301:                T(len = charstr(rdata, edata, &buf, &buflen));
                    302:                if (len == 0)
                    303:                        goto formerr;
                    304:                rdata += len;
                    305:                break;
                    306:
                    307:        case ns_t_txt:
                    308:                while (rdata < edata) {
                    309:                        T(len = charstr(rdata, edata, &buf, &buflen));
                    310:                        if (len == 0)
                    311:                                goto formerr;
                    312:                        rdata += len;
                    313:                        if (rdata < edata)
1.2       christos  314:                                T(addstr(" ", (size_t)1, &buf, &buflen));
1.1       christos  315:                }
                    316:                break;
                    317:
                    318:        case ns_t_nsap: {
                    319:                char t[2+255*3];
                    320:
1.2       christos  321:                (void) inet_nsap_ntoa((int)rdlen, rdata, t);
1.1       christos  322:                T(addstr(t, strlen(t), &buf, &buflen));
                    323:                break;
                    324:            }
                    325:
                    326:        case ns_t_aaaa:
                    327:                if (rdlen != (size_t)NS_IN6ADDRSZ)
                    328:                        goto formerr;
                    329:                (void) inet_ntop(AF_INET6, rdata, buf, buflen);
                    330:                addlen(strlen(buf), &buf, &buflen);
                    331:                break;
                    332:
                    333:        case ns_t_loc: {
                    334:                char t[255];
                    335:
                    336:                /* XXX protocol format checking? */
                    337:                (void) loc_ntoa(rdata, t);
                    338:                T(addstr(t, strlen(t), &buf, &buflen));
                    339:                break;
                    340:            }
                    341:
                    342:        case ns_t_naptr: {
                    343:                u_int order, preference;
                    344:                char t[50];
                    345:
                    346:                if (rdlen < 2U*NS_INT16SZ)
                    347:                        goto formerr;
                    348:
                    349:                /* Order, Precedence. */
                    350:                order = ns_get16(rdata);        rdata += NS_INT16SZ;
                    351:                preference = ns_get16(rdata);   rdata += NS_INT16SZ;
                    352:                len = SPRINTF((t, "%u %u ", order, preference));
1.2       christos  353:                T(addstr(t, (size_t)len, &buf, &buflen));
1.1       christos  354:
                    355:                /* Flags. */
                    356:                T(len = charstr(rdata, edata, &buf, &buflen));
                    357:                if (len == 0)
                    358:                        goto formerr;
                    359:                rdata += len;
1.2       christos  360:                T(addstr(" ", (size_t)1, &buf, &buflen));
1.1       christos  361:
                    362:                /* Service. */
                    363:                T(len = charstr(rdata, edata, &buf, &buflen));
                    364:                if (len == 0)
                    365:                        goto formerr;
                    366:                rdata += len;
1.2       christos  367:                T(addstr(" ", (size_t)1, &buf, &buflen));
1.1       christos  368:
                    369:                /* Regexp. */
                    370:                T(len = charstr(rdata, edata, &buf, &buflen));
                    371:                if (len < 0)
                    372:                        return (-1);
                    373:                if (len == 0)
                    374:                        goto formerr;
                    375:                rdata += len;
1.2       christos  376:                T(addstr(" ", (size_t)1, &buf, &buflen));
1.1       christos  377:
                    378:                /* Server. */
                    379:                T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
                    380:                break;
                    381:            }
                    382:
                    383:        case ns_t_srv: {
                    384:                u_int priority, weight, port;
                    385:                char t[50];
                    386:
                    387:                if (rdlen < 3U*NS_INT16SZ)
                    388:                        goto formerr;
                    389:
                    390:                /* Priority, Weight, Port. */
                    391:                priority = ns_get16(rdata);  rdata += NS_INT16SZ;
                    392:                weight   = ns_get16(rdata);  rdata += NS_INT16SZ;
                    393:                port     = ns_get16(rdata);  rdata += NS_INT16SZ;
                    394:                len = SPRINTF((t, "%u %u %u ", priority, weight, port));
1.2       christos  395:                T(addstr(t, (size_t)len, &buf, &buflen));
1.1       christos  396:
                    397:                /* Server. */
                    398:                T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
                    399:                break;
                    400:            }
                    401:
                    402:        case ns_t_minfo:
                    403:        case ns_t_rp:
                    404:                /* Name1. */
                    405:                T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
1.2       christos  406:                T(addstr(" ", (size_t)1, &buf, &buflen));
1.1       christos  407:
                    408:                /* Name2. */
                    409:                T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
                    410:
                    411:                break;
                    412:
                    413:        case ns_t_wks: {
                    414:                int n, lcnt;
                    415:
                    416:                if (rdlen < 1U + NS_INT32SZ)
                    417:                        goto formerr;
                    418:
                    419:                /* Address. */
                    420:                (void) inet_ntop(AF_INET, rdata, buf, buflen);
                    421:                addlen(strlen(buf), &buf, &buflen);
                    422:                rdata += NS_INADDRSZ;
                    423:
                    424:                /* Protocol. */
                    425:                len = SPRINTF((tmp, " %u ( ", *rdata));
1.2       christos  426:                T(addstr(tmp, (size_t)len, &buf, &buflen));
1.1       christos  427:                rdata += NS_INT8SZ;
                    428:
                    429:                /* Bit map. */
                    430:                n = 0;
                    431:                lcnt = 0;
                    432:                while (rdata < edata) {
                    433:                        u_int c = *rdata++;
                    434:                        do {
                    435:                                if (c & 0200) {
                    436:                                        if (lcnt == 0) {
1.2       christos  437:                                                T(addstr("\n\t\t\t\t", (size_t)5,
1.1       christos  438:                                                         &buf, &buflen));
                    439:                                                lcnt = 10;
                    440:                                                spaced = 0;
                    441:                                        }
                    442:                                        len = SPRINTF((tmp, "%d ", n));
1.2       christos  443:                                        T(addstr(tmp, (size_t)len, &buf, &buflen));
1.1       christos  444:                                        lcnt--;
                    445:                                }
                    446:                                c <<= 1;
                    447:                        } while (++n & 07);
                    448:                }
1.2       christos  449:                T(addstr(")", (size_t)1, &buf, &buflen));
1.1       christos  450:
                    451:                break;
                    452:            }
                    453:
                    454:        case ns_t_key: {
                    455:                char base64_key[NS_MD5RSA_MAX_BASE64];
                    456:                u_int keyflags, protocol, algorithm, key_id;
                    457:                const char *leader;
                    458:                int n;
                    459:
                    460:                if (rdlen < 0U + NS_INT16SZ + NS_INT8SZ + NS_INT8SZ)
                    461:                        goto formerr;
                    462:
                    463:                /* Key flags, Protocol, Algorithm. */
1.3       christos  464: #ifndef _LIBC
1.1       christos  465:                key_id = dst_s_dns_key_id(rdata, edata-rdata);
1.3       christos  466: #else
                    467:                key_id = 0;
                    468: #endif
1.1       christos  469:                keyflags = ns_get16(rdata);  rdata += NS_INT16SZ;
                    470:                protocol = *rdata++;
                    471:                algorithm = *rdata++;
                    472:                len = SPRINTF((tmp, "0x%04x %u %u",
                    473:                               keyflags, protocol, algorithm));
1.2       christos  474:                T(addstr(tmp, (size_t)len, &buf, &buflen));
1.1       christos  475:
                    476:                /* Public key data. */
1.2       christos  477:                len = b64_ntop(rdata, (size_t)(edata - rdata),
1.1       christos  478:                               base64_key, sizeof base64_key);
                    479:                if (len < 0)
                    480:                        goto formerr;
                    481:                if (len > 15) {
1.2       christos  482:                        T(addstr(" (", (size_t)2, &buf, &buflen));
1.1       christos  483:                        leader = "\n\t\t";
                    484:                        spaced = 0;
                    485:                } else
                    486:                        leader = " ";
                    487:                for (n = 0; n < len; n += 48) {
                    488:                        T(addstr(leader, strlen(leader), &buf, &buflen));
1.2       christos  489:                        T(addstr(base64_key + n, (size_t)MIN(len - n, 48),
1.1       christos  490:                                 &buf, &buflen));
                    491:                }
                    492:                if (len > 15)
1.2       christos  493:                        T(addstr(" )", (size_t)2, &buf, &buflen));
1.1       christos  494:                n = SPRINTF((tmp, " ; key_tag= %u", key_id));
1.2       christos  495:                T(addstr(tmp, (size_t)n, &buf, &buflen));
1.1       christos  496:
                    497:                break;
                    498:            }
                    499:
                    500:        case ns_t_sig: {
                    501:                char base64_key[NS_MD5RSA_MAX_BASE64];
1.2       christos  502:                u_int typ, algorithm, labels, footprint;
1.1       christos  503:                const char *leader;
                    504:                u_long t;
                    505:                int n;
                    506:
                    507:                if (rdlen < 22U)
                    508:                        goto formerr;
                    509:
                    510:                /* Type covered, Algorithm, Label count, Original TTL. */
1.2       christos  511:                typ = ns_get16(rdata);  rdata += NS_INT16SZ;
1.1       christos  512:                algorithm = *rdata++;
                    513:                labels = *rdata++;
                    514:                t = ns_get32(rdata);  rdata += NS_INT32SZ;
                    515:                len = SPRINTF((tmp, "%s %d %d %lu ",
1.2       christos  516:                               p_type((int)typ), algorithm, labels, t));
                    517:                T(addstr(tmp, (size_t)len, &buf, &buflen));
1.1       christos  518:                if (labels > (u_int)dn_count_labels(name))
                    519:                        goto formerr;
                    520:
                    521:                /* Signature expiry. */
                    522:                t = ns_get32(rdata);  rdata += NS_INT32SZ;
                    523:                len = SPRINTF((tmp, "%s ", p_secstodate(t)));
1.2       christos  524:                T(addstr(tmp, (size_t)len, &buf, &buflen));
1.1       christos  525:
                    526:                /* Time signed. */
                    527:                t = ns_get32(rdata);  rdata += NS_INT32SZ;
                    528:                len = SPRINTF((tmp, "%s ", p_secstodate(t)));
1.2       christos  529:                T(addstr(tmp, (size_t)len, &buf, &buflen));
1.1       christos  530:
                    531:                /* Signature Footprint. */
                    532:                footprint = ns_get16(rdata);  rdata += NS_INT16SZ;
                    533:                len = SPRINTF((tmp, "%u ", footprint));
1.2       christos  534:                T(addstr(tmp, (size_t)len, &buf, &buflen));
1.1       christos  535:
                    536:                /* Signer's name. */
                    537:                T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
                    538:
                    539:                /* Signature. */
1.2       christos  540:                len = b64_ntop(rdata, (size_t)(edata - rdata),
1.1       christos  541:                               base64_key, sizeof base64_key);
                    542:                if (len > 15) {
1.2       christos  543:                        T(addstr(" (", (size_t)2, &buf, &buflen));
1.1       christos  544:                        leader = "\n\t\t";
                    545:                        spaced = 0;
                    546:                } else
                    547:                        leader = " ";
                    548:                if (len < 0)
                    549:                        goto formerr;
                    550:                for (n = 0; n < len; n += 48) {
                    551:                        T(addstr(leader, strlen(leader), &buf, &buflen));
1.2       christos  552:                        T(addstr(base64_key + n, (size_t)MIN(len - n, 48),
1.1       christos  553:                                 &buf, &buflen));
                    554:                }
                    555:                if (len > 15)
1.2       christos  556:                        T(addstr(" )", (size_t)2, &buf, &buflen));
1.1       christos  557:                break;
                    558:            }
                    559:
                    560:        case ns_t_nxt: {
                    561:                int n, c;
                    562:
                    563:                /* Next domain name. */
                    564:                T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
                    565:
                    566:                /* Type bit map. */
                    567:                n = edata - rdata;
                    568:                for (c = 0; c < n*8; c++)
                    569:                        if (NS_NXT_BIT_ISSET(c, rdata)) {
                    570:                                len = SPRINTF((tmp, " %s", p_type(c)));
1.2       christos  571:                                T(addstr(tmp, (size_t)len, &buf, &buflen));
1.1       christos  572:                        }
                    573:                break;
                    574:            }
                    575:
                    576:        case ns_t_cert: {
                    577:                u_int c_type, key_tag, alg;
                    578:                int n;
                    579:                unsigned int siz;
1.2       christos  580:                char base64_cert[8192], tmp1[40];
1.1       christos  581:                const char *leader;
                    582:
                    583:                c_type  = ns_get16(rdata); rdata += NS_INT16SZ;
                    584:                key_tag = ns_get16(rdata); rdata += NS_INT16SZ;
                    585:                alg = (u_int) *rdata++;
                    586:
1.2       christos  587:                len = SPRINTF((tmp1, "%d %d %d ", c_type, key_tag, alg));
                    588:                T(addstr(tmp1, (size_t)len, &buf, &buflen));
1.1       christos  589:                siz = (edata-rdata)*4/3 + 4; /* "+4" accounts for trailing \0 */
                    590:                if (siz > sizeof(base64_cert) * 3/4) {
                    591:                        const char *str = "record too long to print";
                    592:                        T(addstr(str, strlen(str), &buf, &buflen));
                    593:                }
                    594:                else {
1.2       christos  595:                        len = b64_ntop(rdata, (size_t)(edata-rdata),
                    596:                            base64_cert, siz);
1.1       christos  597:
                    598:                        if (len < 0)
                    599:                                goto formerr;
                    600:                        else if (len > 15) {
1.2       christos  601:                                T(addstr(" (", (size_t)2, &buf, &buflen));
1.1       christos  602:                                leader = "\n\t\t";
                    603:                                spaced = 0;
                    604:                        }
                    605:                        else
                    606:                                leader = " ";
                    607:
                    608:                        for (n = 0; n < len; n += 48) {
                    609:                                T(addstr(leader, strlen(leader),
                    610:                                         &buf, &buflen));
1.2       christos  611:                                T(addstr(base64_cert + n, (size_t)MIN(len - n, 48),
1.1       christos  612:                                         &buf, &buflen));
                    613:                        }
                    614:                        if (len > 15)
1.2       christos  615:                                T(addstr(" )", (size_t)2, &buf, &buflen));
1.1       christos  616:                }
                    617:                break;
                    618:            }
                    619:
                    620:        case ns_t_tkey: {
                    621:                /* KJD - need to complete this */
                    622:                u_long t;
                    623:                int mode, err, keysize;
                    624:
                    625:                /* Algorithm name. */
                    626:                T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
1.2       christos  627:                T(addstr(" ", (size_t)1, &buf, &buflen));
1.1       christos  628:
                    629:                /* Inception. */
                    630:                t = ns_get32(rdata);  rdata += NS_INT32SZ;
                    631:                len = SPRINTF((tmp, "%s ", p_secstodate(t)));
1.2       christos  632:                T(addstr(tmp, (size_t)len, &buf, &buflen));
1.1       christos  633:
                    634:                /* Experation. */
                    635:                t = ns_get32(rdata);  rdata += NS_INT32SZ;
                    636:                len = SPRINTF((tmp, "%s ", p_secstodate(t)));
1.2       christos  637:                T(addstr(tmp, (size_t)len, &buf, &buflen));
1.1       christos  638:
                    639:                /* Mode , Error, Key Size. */
                    640:                /* Priority, Weight, Port. */
                    641:                mode = ns_get16(rdata);  rdata += NS_INT16SZ;
                    642:                err  = ns_get16(rdata);  rdata += NS_INT16SZ;
                    643:                keysize  = ns_get16(rdata);  rdata += NS_INT16SZ;
                    644:                len = SPRINTF((tmp, "%u %u %u ", mode, err, keysize));
1.2       christos  645:                T(addstr(tmp, (size_t)len, &buf, &buflen));
1.1       christos  646:
                    647:                /* XXX need to dump key, print otherdata length & other data */
                    648:                break;
                    649:            }
                    650:
                    651:        case ns_t_tsig: {
                    652:                /* BEW - need to complete this */
                    653:                int n;
                    654:
                    655:                T(len = addname(msg, msglen, &rdata, origin, &buf, &buflen));
1.2       christos  656:                T(addstr(" ", (size_t)1, &buf, &buflen));
1.6       christos  657:                rdata += 8; /*%< time */
1.1       christos  658:                n = ns_get16(rdata); rdata += INT16SZ;
1.6       christos  659:                rdata += n; /*%< sig */
                    660:                n = ns_get16(rdata); rdata += INT16SZ; /*%< original id */
1.1       christos  661:                sprintf(buf, "%d", ns_get16(rdata));
                    662:                rdata += INT16SZ;
                    663:                addlen(strlen(buf), &buf, &buflen);
                    664:                break;
                    665:            }
                    666:
                    667:        case ns_t_a6: {
                    668:                struct in6_addr a;
                    669:                int pbyte, pbit;
                    670:
                    671:                /* prefix length */
                    672:                if (rdlen == 0U) goto formerr;
                    673:                len = SPRINTF((tmp, "%d ", *rdata));
1.2       christos  674:                T(addstr(tmp, (size_t)len, &buf, &buflen));
1.1       christos  675:                pbit = *rdata;
                    676:                if (pbit > 128) goto formerr;
                    677:                pbyte = (pbit & ~7) / 8;
                    678:                rdata++;
                    679:
                    680:                /* address suffix: provided only when prefix len != 128 */
                    681:                if (pbit < 128) {
                    682:                        if (rdata + pbyte >= edata) goto formerr;
                    683:                        memset(&a, 0, sizeof(a));
                    684:                        memcpy(&a.s6_addr[pbyte], rdata, sizeof(a) - pbyte);
                    685:                        (void) inet_ntop(AF_INET6, &a, buf, buflen);
                    686:                        addlen(strlen(buf), &buf, &buflen);
                    687:                        rdata += sizeof(a) - pbyte;
                    688:                }
                    689:
                    690:                /* prefix name: provided only when prefix len > 0 */
                    691:                if (pbit == 0)
                    692:                        break;
                    693:                if (rdata >= edata) goto formerr;
1.2       christos  694:                T(addstr(" ", (size_t)1, &buf, &buflen));
1.1       christos  695:                T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
                    696:
                    697:                break;
                    698:            }
                    699:
                    700:        case ns_t_opt: {
                    701:                len = SPRINTF((tmp, "%u bytes", class));
1.2       christos  702:                T(addstr(tmp, (size_t)len, &buf, &buflen));
1.1       christos  703:                break;
                    704:            }
                    705:
                    706:        default:
                    707:                comment = "unknown RR type";
                    708:                goto hexify;
                    709:        }
                    710:        return (buf - obuf);
                    711:  formerr:
                    712:        comment = "RR format error";
                    713:  hexify: {
                    714:        int n, m;
                    715:        char *p;
                    716:
1.6       christos  717:        len = SPRINTF((tmp, "\\# %u%s\t; %s", (unsigned)(edata - rdata),
                    718:                       rdlen != 0U ? " (" : "", comment));
1.2       christos  719:        T(addstr(tmp, (size_t)len, &buf, &buflen));
1.1       christos  720:        while (rdata < edata) {
                    721:                p = tmp;
                    722:                p += SPRINTF((p, "\n\t"));
                    723:                spaced = 0;
                    724:                n = MIN(16, edata - rdata);
                    725:                for (m = 0; m < n; m++)
                    726:                        p += SPRINTF((p, "%02x ", rdata[m]));
1.2       christos  727:                T(addstr(tmp, (size_t)(p - tmp), &buf, &buflen));
1.1       christos  728:                if (n < 16) {
1.2       christos  729:                        T(addstr(")", (size_t)1, &buf, &buflen));
                    730:                        T(addtab((size_t)(p - tmp + 1), (size_t)48, spaced, &buf, &buflen));
1.1       christos  731:                }
                    732:                p = tmp;
                    733:                p += SPRINTF((p, "; "));
                    734:                for (m = 0; m < n; m++)
                    735:                        *p++ = (isascii(rdata[m]) && isprint(rdata[m]))
                    736:                                ? rdata[m]
                    737:                                : '.';
1.2       christos  738:                T(addstr(tmp, (size_t)(p - tmp), &buf, &buflen));
1.1       christos  739:                rdata += n;
                    740:        }
                    741:        return (buf - obuf);
                    742:     }
                    743: }
                    744:
                    745: /* Private. */
                    746:
1.6       christos  747: /*%
1.1       christos  748:  * size_t
                    749:  * prune_origin(name, origin)
                    750:  *     Find out if the name is at or under the current origin.
                    751:  * return:
                    752:  *     Number of characters in name before start of origin,
                    753:  *     or length of name if origin does not match.
                    754:  * notes:
                    755:  *     This function should share code with samedomain().
                    756:  */
                    757: static size_t
                    758: prune_origin(const char *name, const char *origin) {
                    759:        const char *oname = name;
                    760:
                    761:        while (*name != '\0') {
                    762:                if (origin != NULL && ns_samename(name, origin) == 1)
                    763:                        return (name - oname - (name > oname));
                    764:                while (*name != '\0') {
                    765:                        if (*name == '\\') {
                    766:                                name++;
                    767:                                /* XXX need to handle \nnn form. */
                    768:                                if (*name == '\0')
                    769:                                        break;
                    770:                        } else if (*name == '.') {
                    771:                                name++;
                    772:                                break;
                    773:                        }
                    774:                        name++;
                    775:                }
                    776:        }
                    777:        return (name - oname);
                    778: }
                    779:
1.6       christos  780: /*%
1.1       christos  781:  * int
                    782:  * charstr(rdata, edata, buf, buflen)
                    783:  *     Format a <character-string> into the presentation buffer.
                    784:  * return:
                    785:  *     Number of rdata octets consumed
                    786:  *     0 for protocol format error
                    787:  *     -1 for output buffer error
                    788:  * side effects:
                    789:  *     buffer is advanced on success.
                    790:  */
                    791: static int
                    792: charstr(const u_char *rdata, const u_char *edata, char **buf, size_t *buflen) {
                    793:        const u_char *odata = rdata;
                    794:        size_t save_buflen = *buflen;
                    795:        char *save_buf = *buf;
                    796:
1.2       christos  797:        if (addstr("\"", (size_t)1, buf, buflen) < 0)
1.1       christos  798:                goto enospc;
                    799:        if (rdata < edata) {
                    800:                int n = *rdata;
                    801:
                    802:                if (rdata + 1 + n <= edata) {
                    803:                        rdata++;
                    804:                        while (n-- > 0) {
                    805:                                if (strchr("\n\"\\", *rdata) != NULL)
1.2       christos  806:                                        if (addstr("\\", (size_t)1, buf, buflen) < 0)
1.1       christos  807:                                                goto enospc;
1.2       christos  808:                                if (addstr((const char *)rdata, (size_t)1,
1.1       christos  809:                                           buf, buflen) < 0)
                    810:                                        goto enospc;
                    811:                                rdata++;
                    812:                        }
                    813:                }
                    814:        }
1.2       christos  815:        if (addstr("\"", (size_t)1, buf, buflen) < 0)
1.1       christos  816:                goto enospc;
                    817:        return (rdata - odata);
                    818:  enospc:
                    819:        errno = ENOSPC;
                    820:        *buf = save_buf;
                    821:        *buflen = save_buflen;
                    822:        return (-1);
                    823: }
                    824:
                    825: static int
                    826: addname(const u_char *msg, size_t msglen,
                    827:        const u_char **pp, const char *origin,
                    828:        char **buf, size_t *buflen)
                    829: {
                    830:        size_t newlen, save_buflen = *buflen;
                    831:        char *save_buf = *buf;
                    832:        int n;
                    833:
1.2       christos  834:        n = dn_expand(msg, msg + msglen, *pp, *buf, (int)*buflen);
1.1       christos  835:        if (n < 0)
1.6       christos  836:                goto enospc;    /*%< Guess. */
1.1       christos  837:        newlen = prune_origin(*buf, origin);
                    838:        if (**buf == '\0') {
                    839:                goto root;
                    840:        } else if (newlen == 0U) {
                    841:                /* Use "@" instead of name. */
                    842:                if (newlen + 2 > *buflen)
                    843:                        goto enospc;        /* No room for "@\0". */
                    844:                (*buf)[newlen++] = '@';
                    845:                (*buf)[newlen] = '\0';
                    846:        } else {
                    847:                if (((origin == NULL || origin[0] == '\0') ||
                    848:                    (origin[0] != '.' && origin[1] != '\0' &&
                    849:                    (*buf)[newlen] == '\0')) && (*buf)[newlen - 1] != '.') {
                    850:                        /* No trailing dot. */
                    851:  root:
                    852:                        if (newlen + 2 > *buflen)
                    853:                                goto enospc;    /* No room for ".\0". */
                    854:                        (*buf)[newlen++] = '.';
                    855:                        (*buf)[newlen] = '\0';
                    856:                }
                    857:        }
                    858:        *pp += n;
                    859:        addlen(newlen, buf, buflen);
                    860:        **buf = '\0';
                    861:        return (newlen);
                    862:  enospc:
                    863:        errno = ENOSPC;
                    864:        *buf = save_buf;
                    865:        *buflen = save_buflen;
                    866:        return (-1);
                    867: }
                    868:
                    869: static void
                    870: addlen(size_t len, char **buf, size_t *buflen) {
                    871:        INSIST(len <= *buflen);
                    872:        *buf += len;
                    873:        *buflen -= len;
                    874: }
                    875:
                    876: static int
                    877: addstr(const char *src, size_t len, char **buf, size_t *buflen) {
                    878:        if (len >= *buflen) {
                    879:                errno = ENOSPC;
                    880:                return (-1);
                    881:        }
                    882:        memcpy(*buf, src, len);
                    883:        addlen(len, buf, buflen);
                    884:        **buf = '\0';
                    885:        return (0);
                    886: }
                    887:
                    888: static int
                    889: addtab(size_t len, size_t target, int spaced, char **buf, size_t *buflen) {
                    890:        size_t save_buflen = *buflen;
                    891:        char *save_buf = *buf;
                    892:        int t;
                    893:
                    894:        if (spaced || len >= target - 1) {
1.2       christos  895:                T(addstr("  ", (size_t)2, buf, buflen));
1.1       christos  896:                spaced = 1;
                    897:        } else {
                    898:                for (t = (target - len - 1) / 8; t >= 0; t--)
1.2       christos  899:                        if (addstr("\t", (size_t)1, buf, buflen) < 0) {
1.1       christos  900:                                *buflen = save_buflen;
                    901:                                *buf = save_buf;
                    902:                                return (-1);
                    903:                        }
                    904:                spaced = 0;
                    905:        }
                    906:        return (spaced);
                    907: }
1.6       christos  908:
                    909: /*! \file */

CVSweb <webmaster@jp.NetBSD.org>