(linenum→info "unix/slp.c:2238")

glibc/2.7/resolv/ns_print.c

    1: /*
    2:  * Copyright (c) 1996-1999 by Internet Software Consortium.
    3:  *
    4:  * Permission to use, copy, modify, and distribute this software for any
    5:  * purpose with or without fee is hereby granted, provided that the above
    6:  * copyright notice and this permission notice appear in all copies.
    7:  *
    8:  * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
    9:  * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
   10:  * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
   11:  * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
   12:  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
   13:  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
   14:  * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
   15:  * SOFTWARE.
   16:  */
   17: 
   18: #if !defined(_LIBC) && !defined(lint)
   19: static const char rcsid[] = "$BINDId: ns_print.c,v 8.18 2000/02/29 05:48:12 vixie Exp $";
   20: #endif
   21: 
   22: /* Import. */
   23: 
   24: #include <sys/types.h>
   25: #include <sys/socket.h>
   26: 
   27: #include <netinet/in.h>
   28: #include <arpa/nameser.h>
   29: #include <arpa/inet.h>
   30: 
   31: #include <assert.h>
   32: #include <errno.h>
   33: #include <resolv.h>
   34: #include <string.h>
   35: #include <ctype.h>
   36: 
   37: #ifdef SPRINTF_CHAR
   38: # define SPRINTF(x) strlen(sprintf/**/x)
   39: #else
   40: # define SPRINTF(x) ((size_t)sprintf x)
   41: #endif
   42: 
   43: /* Forward. */
   44: 
   45: static size_t   prune_origin(const char *name, const char *origin);
   46: static int      charstr(const u_char *rdata, const u_char *edata,
   47:                         char **buf, size_t *buflen);
   48: static int      addname(const u_char *msg, size_t msglen,
   49:                         const u_char **p, const char *origin,
   50:                         char **buf, size_t *buflen);
   51: static void     addlen(size_t len, char **buf, size_t *buflen);
   52: static int      addstr(const char *src, size_t len,
   53:                        char **buf, size_t *buflen);
   54: static int      addtab(size_t len, size_t target, int spaced,
   55:                        char **buf, size_t *buflen);
   56: 
   57: /* Proto. */
   58: 
   59: #ifndef _LIBC
   60: u_int16_t       dst_s_dns_key_id(const u_char *, const int);
   61: #endif
   62: 
   63: /* Macros. */
   64: 
   65: #define T(x) \
   66:         do { \
   67:                 if ((x) < 0) \
   68:                         return (-1); \
   69:         } while (0)
   70: 
   71: /* Public. */
   72: 
   73: /*
   74:  * int
   75:  * ns_sprintrr(handle, rr, name_ctx, origin, buf, buflen)
   76:  *      Convert an RR to presentation format.
   77:  * return:
   78:  *      Number of characters written to buf, or -1 (check errno).
   79:  */
   80: int
   81: ns_sprintrr(const ns_msg *handle, const ns_rr *rr,
   82:             const char *name_ctx, const char *origin,
   83:             char *buf, size_t buflen)
   84: {
   85:         int n;
   86: 
   87:         n = ns_sprintrrf(ns_msg_base(*handle), ns_msg_size(*handle),
   88:                          ns_rr_name(*rr), ns_rr_class(*rr), ns_rr_type(*rr),
   89:                          ns_rr_ttl(*rr), ns_rr_rdata(*rr), ns_rr_rdlen(*rr),
   90:                          name_ctx, origin, buf, buflen);
   91:         return (n);
   92: }
   93: 
   94: /*
   95:  * int
   96:  * ns_sprintrrf(msg, msglen, name, class, type, ttl, rdata, rdlen,
   97:  *             name_ctx, origin, buf, buflen)
   98:  *      Convert the fields of an RR into presentation format.
   99:  * return:
  100:  *      Number of characters written to buf, or -1 (check errno).
  101:  */
  102: int
  103: ns_sprintrrf(const u_char *msg, size_t msglen,
  104:             const char *name, ns_class class, ns_type type,
  105:             u_long ttl, const u_char *rdata, size_t rdlen,
  106:             const char *name_ctx, const char *origin,
  107:             char *buf, size_t buflen)
  108: {
  109:         const char *obuf = buf;
  110:         const u_char *edata = rdata + rdlen;
  111:         int spaced = 0;
  112: 
  113:         const char *comment;
  114:         char tmp[100];
  115:         char errbuf[40];
  116:         int len, x;
  117: 
  118:         /*
  119:          * Owner.
  120:          */
  121:         if (name_ctx != NULL && ns_samename(name_ctx, name) == 1) {
  122:                 T(addstr("\t\t\t", 3, &buf, &buflen));
  123:         } else {
  124:                 len = prune_origin(name, origin);
  125:                 if (len == 0) {
  126:                         T(addstr("@\t\t\t", 4, &buf, &buflen));
  127:                 } else {
  128:                         T(addstr(name, len, &buf, &buflen));
  129:                         /* Origin not used or not root, and no trailing dot? */
  130:                         if (((origin == NULL || origin[0] == '\0') ||
  131:                             (origin[0] != '.' && origin[1] != '\0' &&
  132:                             name[len] == '\0')) && name[len - 1] != '.') {
  133:                                 T(addstr(".", 1, &buf, &buflen));
  134:                                 len++;
  135:                         }
  136:                         T(spaced = addtab(len, 24, spaced, &buf, &buflen));
  137:                 }
  138:         }
  139: 
  140:         /*
  141:          * TTL, Class, Type.
  142:          */
  143:         T(x = ns_format_ttl(ttl, buf, buflen));
  144:         addlen(x, &buf, &buflen);
  145:         len = SPRINTF((tmp, " %s %s", p_class(class), p_type(type)));
  146:         T(addstr(tmp, len, &buf, &buflen));
  147:         T(spaced = addtab(x + len, 16, spaced, &buf, &buflen));
  148: 
  149:         /*
  150:          * RData.
  151:          */
  152:         switch (type) {
  153:         case ns_t_a:
  154:                 if (rdlen != NS_INADDRSZ)
  155:                         goto formerr;
  156:                 (void) inet_ntop(AF_INET, rdata, buf, buflen);
  157:                 addlen(strlen(buf), &buf, &buflen);
  158:                 break;
  159: 
  160:         case ns_t_cname:
  161:         case ns_t_mb:
  162:         case ns_t_mg:
  163:         case ns_t_mr:
  164:         case ns_t_ns:
  165:         case ns_t_ptr:
  166:                 T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
  167:                 break;
  168: 
  169:         case ns_t_hinfo:
  170:         case ns_t_isdn:
  171:                 /* First word. */
  172:                 T(len = charstr(rdata, edata, &buf, &buflen));
  173:                 if (len == 0)
  174:                         goto formerr;
  175:                 rdata += len;
  176:                 T(addstr(" ", 1, &buf, &buflen));
  177: 
  178: 
  179:                 /* Second word, optional in ISDN records. */
  180:                 if (type == ns_t_isdn && rdata == edata)
  181:                         break;
  182: 
  183:                 T(len = charstr(rdata, edata, &buf, &buflen));
  184:                 if (len == 0)
  185:                         goto formerr;
  186:                 rdata += len;
  187:                 break;
  188: 
  189:         case ns_t_soa: {
  190:                 u_long t;
  191: 
  192:                 /* Server name. */
  193:                 T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
  194:                 T(addstr(" ", 1, &buf, &buflen));
  195: 
  196:                 /* Administrator name. */
  197:                 T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
  198:                 T(addstr(" (\n", 3, &buf, &buflen));
  199:                 spaced = 0;
  200: 
  201:                 if ((edata - rdata) != 5*NS_INT32SZ)
  202:                         goto formerr;
  203: 
  204:                 /* Serial number. */
  205:                 t = ns_get32(rdata);  rdata += NS_INT32SZ;
  206:                 T(addstr("\t\t\t\t\t", 5, &buf, &buflen));
  207:                 len = SPRINTF((tmp, "%lu", t));
  208:                 T(addstr(tmp, len, &buf, &buflen));
  209:                 T(spaced = addtab(len, 16, spaced, &buf, &buflen));
  210:                 T(addstr("; serial\n", 9, &buf, &buflen));
  211:                 spaced = 0;
  212: 
  213:                 /* Refresh interval. */
  214:                 t = ns_get32(rdata);  rdata += NS_INT32SZ;
  215:                 T(addstr("\t\t\t\t\t", 5, &buf, &buflen));
  216:                 T(len = ns_format_ttl(t, buf, buflen));
  217:                 addlen(len, &buf, &buflen);
  218:                 T(spaced = addtab(len, 16, spaced, &buf, &buflen));
  219:                 T(addstr("; refresh\n", 10, &buf, &buflen));
  220:                 spaced = 0;
  221: 
  222:                 /* Retry interval. */
  223:                 t = ns_get32(rdata);  rdata += NS_INT32SZ;
  224:                 T(addstr("\t\t\t\t\t", 5, &buf, &buflen));
  225:                 T(len = ns_format_ttl(t, buf, buflen));
  226:                 addlen(len, &buf, &buflen);
  227:                 T(spaced = addtab(len, 16, spaced, &buf, &buflen));
  228:                 T(addstr("; retry\n", 8, &buf, &buflen));
  229:                 spaced = 0;
  230: 
  231:                 /* Expiry. */
  232:                 t = ns_get32(rdata);  rdata += NS_INT32SZ;
  233:                 T(addstr("\t\t\t\t\t", 5, &buf, &buflen));
  234:                 T(len = ns_format_ttl(t, buf, buflen));
  235:                 addlen(len, &buf, &buflen);
  236:                 T(spaced = addtab(len, 16, spaced, &buf, &buflen));
  237:                 T(addstr("; expiry\n", 9, &buf, &buflen));
  238:                 spaced = 0;
  239: 
  240:                 /* Minimum TTL. */
  241:                 t = ns_get32(rdata);  rdata += NS_INT32SZ;
  242:                 T(addstr("\t\t\t\t\t", 5, &buf, &buflen));
  243:                 T(len = ns_format_ttl(t, buf, buflen));
  244:                 addlen(len, &buf, &buflen);
  245:                 T(addstr(" )", 2, &buf, &buflen));
  246:                 T(spaced = addtab(len, 16, spaced, &buf, &buflen));
  247:                 T(addstr("; minimum\n", 10, &buf, &buflen));
  248: 
  249:                 break;
  250:             }
  251: 
  252:         case ns_t_mx:
  253:         case ns_t_afsdb:
  254:         case ns_t_rt: {
  255:                 u_int t;
  256: 
  257:                 if (rdlen < NS_INT16SZ)
  258:                         goto formerr;
  259: 
  260:                 /* Priority. */
  261:                 t = ns_get16(rdata);
  262:                 rdata += NS_INT16SZ;
  263:                 len = SPRINTF((tmp, "%u ", t));
  264:                 T(addstr(tmp, len, &buf, &buflen));
  265: 
  266:                 /* Target. */
  267:                 T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
  268: 
  269:                 break;
  270:             }
  271: 
  272:         case ns_t_px: {
  273:                 u_int t;
  274: 
  275:                 if (rdlen < NS_INT16SZ)
  276:                         goto formerr;
  277: 
  278:                 /* Priority. */
  279:                 t = ns_get16(rdata);
  280:                 rdata += NS_INT16SZ;
  281:                 len = SPRINTF((tmp, "%u ", t));
  282:                 T(addstr(tmp, len, &buf, &buflen));
  283: 
  284:                 /* Name1. */
  285:                 T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
  286:                 T(addstr(" ", 1, &buf, &buflen));
  287: 
  288:                 /* Name2. */
  289:                 T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
  290: 
  291:                 break;
  292:             }
  293: 
  294:         case ns_t_x25:
  295:                 T(len = charstr(rdata, edata, &buf, &buflen));
  296:                 if (len == 0)
  297:                         goto formerr;
  298:                 rdata += len;
  299:                 break;
  300: 
  301:         case ns_t_txt:
  302:                 while (rdata < edata) {
  303:                         T(len = charstr(rdata, edata, &buf, &buflen));
  304:                         if (len == 0)
  305:                                 goto formerr;
  306:                         rdata += len;
  307:                         if (rdata < edata)
  308:                                 T(addstr(" ", 1, &buf, &buflen));
  309:                 }
  310:                 break;
  311: 
  312:         case ns_t_nsap: {
  313:                 /* 2*255 for hex digits, 128 for '.' and '\0', 2 for
  314:                    0x if inet_nsap_ntoa starts using it.  */
  315:                 char t[255*2 + 128 + 2];
  316: 
  317:                 (void) inet_nsap_ntoa(rdlen, rdata, t);
  318:                 T(addstr(t, strlen(t), &buf, &buflen));
  319:                 break;
  320:             }
  321: 
  322:         case ns_t_aaaa:
  323:                 if (rdlen != NS_IN6ADDRSZ)
  324:                         goto formerr;
  325:                 (void) inet_ntop(AF_INET6, rdata, buf, buflen);
  326:                 addlen(strlen(buf), &buf, &buflen);
  327:                 break;
  328: 
  329:         case ns_t_loc: {
  330:                 char t[255];
  331: 
  332:                 /* XXX protocol format checking? */
  333:                 (void) loc_ntoa(rdata, t);
  334:                 T(addstr(t, strlen(t), &buf, &buflen));
  335:                 break;
  336:             }
  337: 
  338:         case ns_t_naptr: {
  339:                 u_int order, preference;
  340:                 char t[50];
  341: 
  342:                 if (rdlen < 2*NS_INT16SZ)
  343:                         goto formerr;
  344: 
  345:                 /* Order, Precedence. */
  346:                 order = ns_get16(rdata);      rdata += NS_INT16SZ;
  347:                 preference = ns_get16(rdata); rdata += NS_INT16SZ;
  348:                 len = SPRINTF((t, "%u %u ", order, preference));
  349:                 T(addstr(t, len, &buf, &buflen));
  350: 
  351:                 /* Flags. */
  352:                 T(len = charstr(rdata, edata, &buf, &buflen));
  353:                 if (len == 0)
  354:                         goto formerr;
  355:                 rdata += len;
  356:                 T(addstr(" ", 1, &buf, &buflen));
  357: 
  358:                 /* Service. */
  359:                 T(len = charstr(rdata, edata, &buf, &buflen));
  360:                 if (len == 0)
  361:                         goto formerr;
  362:                 rdata += len;
  363:                 T(addstr(" ", 1, &buf, &buflen));
  364: 
  365:                 /* Regexp. */
  366:                 T(len = charstr(rdata, edata, &buf, &buflen));
  367:                 if (len < 0)
  368:                         return (-1);
  369:                 if (len == 0)
  370:                         goto formerr;
  371:                 rdata += len;
  372:                 T(addstr(" ", 1, &buf, &buflen));
  373: 
  374:                 /* Server. */
  375:                 T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
  376:                 break;
  377:             }
  378: 
  379:         case ns_t_srv: {
  380:                 u_int priority, weight, port;
  381:                 char t[50];
  382: 
  383:                 if (rdlen < NS_INT16SZ*3)
  384:                         goto formerr;
  385: 
  386:                 /* Priority, Weight, Port. */
  387:                 priority = ns_get16(rdata);  rdata += NS_INT16SZ;
  388:                 weight   = ns_get16(rdata);  rdata += NS_INT16SZ;
  389:                 port     = ns_get16(rdata);  rdata += NS_INT16SZ;
  390:                 len = SPRINTF((t, "%u %u %u ", priority, weight, port));
  391:                 T(addstr(t, len, &buf, &buflen));
  392: 
  393:                 /* Server. */
  394:                 T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
  395:                 break;
  396:             }
  397: 
  398:         case ns_t_minfo:
  399:         case ns_t_rp:
  400:                 /* Name1. */
  401:                 T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
  402:                 T(addstr(" ", 1, &buf, &buflen));
  403: 
  404:                 /* Name2. */
  405:                 T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
  406: 
  407:                 break;
  408: 
  409:         case ns_t_wks: {
  410:                 int n, lcnt;
  411: 
  412:                 if (rdlen < NS_INT32SZ + 1)
  413:                         goto formerr;
  414: 
  415:                 /* Address. */
  416:                 (void) inet_ntop(AF_INET, rdata, buf, buflen);
  417:                 addlen(strlen(buf), &buf, &buflen);
  418:                 rdata += NS_INADDRSZ;
  419: 
  420:                 /* Protocol. */
  421:                 len = SPRINTF((tmp, " %u ( ", *rdata));
  422:                 T(addstr(tmp, len, &buf, &buflen));
  423:                 rdata += NS_INT8SZ;
  424: 
  425:                 /* Bit map. */
  426:                 n = 0;
  427:                 lcnt = 0;
  428:                 while (rdata < edata) {
  429:                         u_int c = *rdata++;
  430:                         do {
  431:                                 if (c & 0200) {
  432:                                         if (lcnt == 0) {
  433:                                                 T(addstr("\n\t\t\t\t", 5,
  434:                                                          &buf, &buflen));
  435:                                                 lcnt = 10;
  436:                                                 spaced = 0;
  437:                                         }
  438:                                         len = SPRINTF((tmp, "%d ", n));
  439:                                         T(addstr(tmp, len, &buf, &buflen));
  440:                                         lcnt--;
  441:                                 }
  442:                                 c <<= 1;
  443:                         } while (++n & 07);
  444:                 }
  445:                 T(addstr(")", 1, &buf, &buflen));
  446: 
  447:                 break;
  448:             }
  449: 
  450:         case ns_t_key: {
  451: #ifndef _LIBC
  452:                 char base64_key[NS_MD5RSA_MAX_BASE64];
  453:                 u_int keyflags, protocol, algorithm, key_id;
  454:                 const char *leader;
  455:                 int n;
  456: 
  457:                 if (rdlen < NS_INT16SZ + NS_INT8SZ + NS_INT8SZ)
  458:                         goto formerr;
  459: 
  460:                 /* Key flags, Protocol, Algorithm. */
  461:                 key_id = dst_s_dns_key_id(rdata, edata-rdata);
  462:                 keyflags = ns_get16(rdata);  rdata += NS_INT16SZ;
  463:                 protocol = *rdata++;
  464:                 algorithm = *rdata++;
  465:                 len = SPRINTF((tmp, "0x%04x %u %u",
  466:                                keyflags, protocol, algorithm));
  467:                 T(addstr(tmp, len, &buf, &buflen));
  468: 
  469:                 /* Public key data. */
  470:                 len = b64_ntop(rdata, edata - rdata,
  471:                                base64_key, sizeof base64_key);
  472:                 if (len < 0)
  473:                         goto formerr;
  474:                 if (len > 15) {
  475:                         T(addstr(" (", 2, &buf, &buflen));
  476:                         leader = "\n\t\t";
  477:                         spaced = 0;
  478:                 } else
  479:                         leader = " ";
  480:                 for (n = 0; n < len; n += 48) {
  481:                         T(addstr(leader, strlen(leader), &buf, &buflen));
  482:                         T(addstr(base64_key + n, MIN(len - n, 48),
  483:                                  &buf, &buflen));
  484:                 }
  485:                 if (len > 15)
  486:                         T(addstr(" )", 2, &buf, &buflen));
  487:                 n = SPRINTF((tmp, " ; key_tag= %u", key_id));
  488:                 T(addstr(tmp, n, &buf, &buflen));
  489: #endif /* !_LIBC */
  490: 
  491:                 break;
  492:             }
  493: 
  494:         case ns_t_sig: {
  495: #ifndef _LIBC
  496:                 char base64_key[NS_MD5RSA_MAX_BASE64];
  497:                 u_int type, algorithm, labels, footprint;
  498:                 const char *leader;
  499:                 u_long t;
  500:                 int n;
  501: 
  502:                 if (rdlen < 22)
  503:                         goto formerr;
  504: 
  505:                 /* Type covered, Algorithm, Label count, Original TTL. */
  506:                 type = ns_get16(rdata);  rdata += NS_INT16SZ;
  507:                 algorithm = *rdata++;
  508:                 labels = *rdata++;
  509:                 t = ns_get32(rdata);  rdata += NS_INT32SZ;
  510:                 len = SPRINTF((tmp, "%s %d %d %lu ",
  511:                                p_type(type), algorithm, labels, t));
  512:                 T(addstr(tmp, len, &buf, &buflen));
  513:                 if (labels > (u_int)dn_count_labels(name))
  514:                         goto formerr;
  515: 
  516:                 /* Signature expiry. */
  517:                 t = ns_get32(rdata);  rdata += NS_INT32SZ;
  518:                 len = SPRINTF((tmp, "%s ", p_secstodate(t)));
  519:                 T(addstr(tmp, len, &buf, &buflen));
  520: 
  521:                 /* Time signed. */
  522:                 t = ns_get32(rdata);  rdata += NS_INT32SZ;
  523: