Annotation of embedaddon/dhcp/minires/ns_name.c, revision 1.1.1.1

1.1       misho       1: /*
                      2:  * Copyright (c) 2004,2009 by Internet Systems Consortium, Inc. ("ISC")
                      3:  * Copyright (c) 1996-2003 by Internet Software Consortium
                      4:  *
                      5:  * Permission to use, copy, modify, and distribute this software for any
                      6:  * purpose with or without fee is hereby granted, provided that the above
                      7:  * copyright notice and this permission notice appear in all copies.
                      8:  *
                      9:  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
                     10:  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
                     11:  * MERCHANTABILITY AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR
                     12:  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
                     13:  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
                     14:  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
                     15:  * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
                     16:  *
                     17:  *   Internet Systems Consortium, Inc.
                     18:  *   950 Charter Street
                     19:  *   Redwood City, CA 94063
                     20:  *   <info@isc.org>
                     21:  *   https://www.isc.org/
                     22:  */
                     23: 
                     24: #ifndef lint
1.1.1.1 ! misho      25: static const char rcsid[] = "$Id: ns_name.c,v 1.2.786.3 2009/07/24 22:04:52 sar Exp $";
1.1       misho      26: #endif
                     27: 
                     28: #include <sys/types.h>
                     29: 
                     30: #include <netinet/in.h>
                     31: #include <sys/socket.h>
                     32: 
                     33: #include <errno.h>
                     34: #include <string.h>
                     35: #include <ctype.h>
                     36: 
                     37: #include "minires/minires.h"
                     38: #include "arpa/nameser.h"
                     39: 
                     40: /* Data. */
                     41: 
                     42: static const char      digits[] = "0123456789";
                     43: 
                     44: /* Forward. */
                     45: 
                     46: static int             special(int);
                     47: static int             printable(int);
                     48: static int             dn_find(const u_char *, const u_char *,
                     49:                                const u_char * const *,
                     50:                                const u_char * const *);
                     51: 
                     52: /* Public. */
                     53: 
                     54: /*
                     55:  * ns_name_ntop(src, dst, dstsiz)
                     56:  *     Convert an encoded domain name to printable ascii as per RFC1035.
                     57:  * return:
                     58:  *     Number of bytes written to buffer, or -1 (with errno set)
                     59:  * notes:
                     60:  *     The root is returned as "."
                     61:  *     All other domains are returned in non absolute form
                     62:  */
                     63: int
                     64: ns_name_ntop(const u_char *src, char *dst, size_t dstsiz) {
                     65:        const u_char *cp;
                     66:        char *dn, *eom;
                     67:        u_char c;
                     68:        u_int n;
                     69: 
                     70:        cp = src;
                     71:        dn = dst;
                     72:        eom = dst + dstsiz;
                     73: 
                     74:        if (dn >= eom) {
                     75:                errno = EMSGSIZE;
                     76:                return (-1);
                     77:        }
                     78: 
                     79:        while ((n = *cp++) != 0) {
                     80:                if ((n & NS_CMPRSFLGS) != 0) {
                     81:                        /* Some kind of compression pointer. */
                     82:                        errno = EMSGSIZE;
                     83:                        return (-1);
                     84:                }
                     85:                if (dn != dst) {
                     86:                        if (dn >= eom) {
                     87:                                errno = EMSGSIZE;
                     88:                                return (-1);
                     89:                        }
                     90:                        *dn++ = '.';
                     91:                }
                     92:                if (dn + n >= eom) {
                     93:                        errno = EMSGSIZE;
                     94:                        return (-1);
                     95:                }
                     96:                for ((void)NULL; n > 0; n--) {
                     97:                        c = *cp++;
                     98:                        if (special(c)) {
                     99:                                if (dn + 1 >= eom) {
                    100:                                        errno = EMSGSIZE;
                    101:                                        return (-1);
                    102:                                }
                    103:                                *dn++ = '\\';
                    104:                                *dn++ = (char)c;
                    105:                        } else if (!printable(c)) {
                    106:                                if (dn + 3 >= eom) {
                    107:                                        errno = EMSGSIZE;
                    108:                                        return (-1);
                    109:                                }
                    110:                                *dn++ = '\\';
                    111:                                *dn++ = digits[c / 100];
                    112:                                *dn++ = digits[(c % 100) / 10];
                    113:                                *dn++ = digits[c % 10];
                    114:                        } else {
                    115:                                if (dn >= eom) {
                    116:                                        errno = EMSGSIZE;
                    117:                                        return (-1);
                    118:                                }
                    119:                                *dn++ = (char)c;
                    120:                        }
                    121:                }
                    122:        }
                    123:        if (dn == dst) {
                    124:                if (dn >= eom) {
                    125:                        errno = EMSGSIZE;
                    126:                        return (-1);
                    127:                }
                    128:                *dn++ = '.';
                    129:        }
                    130:        if (dn >= eom) {
                    131:                errno = EMSGSIZE;
                    132:                return (-1);
                    133:        }
                    134:        *dn++ = '\0';
                    135:        return (dn - dst);
                    136: }
                    137: 
                    138: /*
                    139:  * ns_name_pton(src, dst, dstsiz)
                    140:  *     Convert a ascii string into an encoded domain name as per RFC1035.
                    141:  * return:
                    142:  *     -1 if it fails
                    143:  *     1 if string was fully qualified
                    144:  *     0 is string was not fully qualified
                    145:  * notes:
                    146:  *     Enforces label and domain length limits.
                    147:  */
                    148: 
                    149: int
                    150: ns_name_pton(const char *src, u_char *dst, size_t dstsiz) {
                    151:        u_char *label, *bp, *eom;
                    152:        int c, n, escaped;
                    153:        char *cp;
                    154: 
                    155:        escaped = 0;
                    156:        bp = dst;
                    157:        eom = dst + dstsiz;
                    158:        label = bp++;
                    159: 
                    160:        while ((c = *src++) != 0) {
                    161:                if (escaped) {
                    162:                        if ((cp = strchr(digits, c)) != NULL) {
                    163:                                n = (cp - digits) * 100;
                    164:                                if ((c = *src++) == 0 ||
                    165:                                    (cp = strchr(digits, c)) == NULL) {
                    166:                                        errno = EMSGSIZE;
                    167:                                        return (-1);
                    168:                                }
                    169:                                n += (cp - digits) * 10;
                    170:                                if ((c = *src++) == 0 ||
                    171:                                    (cp = strchr(digits, c)) == NULL) {
                    172:                                        errno = EMSGSIZE;
                    173:                                        return (-1);
                    174:                                }
                    175:                                n += (cp - digits);
                    176:                                if (n > 255) {
                    177:                                        errno = EMSGSIZE;
                    178:                                        return (-1);
                    179:                                }
                    180:                                c = n;
                    181:                        }
                    182:                        escaped = 0;
                    183:                } else if (c == '\\') {
                    184:                        escaped = 1;
                    185:                        continue;
                    186:                } else if (c == '.') {
                    187:                        c = (bp - label - 1);
                    188:                        if ((c & NS_CMPRSFLGS) != 0) {  /* Label too big. */
                    189:                                errno = EMSGSIZE;
                    190:                                return (-1);
                    191:                        }
                    192:                        if (label >= eom) {
                    193:                                errno = EMSGSIZE;
                    194:                                return (-1);
                    195:                        }
                    196:                        *label = c;
                    197:                        /* Fully qualified ? */
                    198:                        if (*src == '\0') {
                    199:                                if (c != 0) {
                    200:                                        if (bp >= eom) {
                    201:                                                errno = EMSGSIZE;
                    202:                                                return (-1);
                    203:                                        }
                    204:                                        *bp++ = '\0';
                    205:                                }
                    206:                                if ((bp - dst) > MAXCDNAME) {
                    207:                                        errno = EMSGSIZE;
                    208:                                        return (-1);
                    209:                                }
                    210:                                return (1);
                    211:                        }
                    212:                        if (c == 0 || *src == '.') {
                    213:                                errno = EMSGSIZE;
                    214:                                return (-1);
                    215:                        }
                    216:                        label = bp++;
                    217:                        continue;
                    218:                }
                    219:                if (bp >= eom) {
                    220:                        errno = EMSGSIZE;
                    221:                        return (-1);
                    222:                }
                    223:                *bp++ = (u_char)c;
                    224:        }
                    225:        c = (bp - label - 1);
                    226:        if ((c & NS_CMPRSFLGS) != 0) {          /* Label too big. */
                    227:                errno = EMSGSIZE;
                    228:                return (-1);
                    229:        }
                    230:        if (label >= eom) {
                    231:                errno = EMSGSIZE;
                    232:                return (-1);
                    233:        }
                    234:        *label = c;
                    235:        if (c != 0) {
                    236:                if (bp >= eom) {
                    237:                        errno = EMSGSIZE;
                    238:                        return (-1);
                    239:                }
                    240:                *bp++ = 0;
                    241:        }
                    242:        if ((bp - dst) > MAXCDNAME) {   /* src too big */
                    243:                errno = EMSGSIZE;
                    244:                return (-1);
                    245:        }
                    246:        return (0);
                    247: }
                    248: 
                    249: /*
                    250:  * ns_name_ntol(src, dst, dstsiz)
                    251:  *     Convert a network strings labels into all lowercase.
                    252:  * return:
                    253:  *     Number of bytes written to buffer, or -1 (with errno set)
                    254:  * notes:
                    255:  *     Enforces label and domain length limits.
                    256:  */
                    257: 
                    258: int
                    259: ns_name_ntol(const u_char *src, u_char *dst, size_t dstsiz) {
                    260:        const u_char *cp;
                    261:        u_char *dn, *eom;
                    262:        u_char c;
                    263:        u_int n;
                    264: 
                    265:        cp = src;
                    266:        dn = dst;
                    267:        eom = dst + dstsiz;
                    268: 
                    269:        if (dn >= eom) {
                    270:                errno = EMSGSIZE;
                    271:                return (-1);
                    272:        }
                    273:        while ((n = *cp++) != 0) {
                    274:                if ((n & NS_CMPRSFLGS) != 0) {
                    275:                        /* Some kind of compression pointer. */
                    276:                        errno = EMSGSIZE;
                    277:                        return (-1);
                    278:                }
                    279:                *dn++ = n;
                    280:                if (dn + n >= eom) {
                    281:                        errno = EMSGSIZE;
                    282:                        return (-1);
                    283:                }
                    284:                for ((void)NULL; n > 0; n--) {
                    285:                        c = *cp++;
                    286:                        if (isupper(c))
                    287:                                *dn++ = tolower(c);
                    288:                        else
                    289:                                *dn++ = c;
                    290:                }
                    291:        }
                    292:        *dn++ = '\0';
                    293:        return (dn - dst);
                    294: }
                    295: 
                    296: /*
                    297:  * ns_name_unpack(msg, eom, src, dst, dstsiz)
                    298:  *     Unpack a domain name from a message, source may be compressed.
                    299:  * return:
                    300:  *     -1 if it fails, or consumed octets if it succeeds.
                    301:  */
                    302: int
                    303: ns_name_unpack(const u_char *msg, const u_char *eom, const u_char *src,
                    304:               u_char *dst, size_t dstsiz)
                    305: {
                    306:        const u_char *srcp, *dstlim;
                    307:        u_char *dstp;
                    308:        unsigned n;
                    309:        int len;
                    310:        int checked;
                    311: 
                    312:        len = -1;
                    313:        checked = 0;
                    314:        dstp = dst;
                    315:        srcp = src;
                    316:        dstlim = dst + dstsiz;
                    317:        if (srcp < msg || srcp >= eom) {
                    318:                errno = EMSGSIZE;
                    319:                return (-1);
                    320:        }
                    321:        /* Fetch next label in domain name. */
                    322:        while ((n = *srcp++) != 0) {
                    323:                /* Check for indirection. */
                    324:                switch (n & NS_CMPRSFLGS) {
                    325:                case 0:
                    326:                        /* Limit checks. */
                    327:                        if (dstp + n + 1 >= dstlim || srcp + n >= eom) {
                    328:                                errno = EMSGSIZE;
                    329:                                return (-1);
                    330:                        }
                    331:                        checked += n + 1;
                    332:                        *dstp++ = n;
                    333:                        memcpy(dstp, srcp, n);
                    334:                        dstp += n;
                    335:                        srcp += n;
                    336:                        break;
                    337: 
                    338:                case NS_CMPRSFLGS:
                    339:                        if (srcp >= eom) {
                    340:                                errno = EMSGSIZE;
                    341:                                return (-1);
                    342:                        }
                    343:                        if (len < 0)
                    344:                                len = srcp - src + 1;
                    345:                        srcp = msg + (((n & 0x3f) << 8) | (*srcp & 0xff));
                    346:                        if (srcp < msg || srcp >= eom) {  /* Out of range. */
                    347:                                errno = EMSGSIZE;
                    348:                                return (-1);
                    349:                        }
                    350:                        checked += 2;
                    351:                        /*
                    352:                         * Check for loops in the compressed name;
                    353:                         * if we've looked at the whole message,
                    354:                         * there must be a loop.
                    355:                         */
                    356:                        if (checked >= eom - msg) {
                    357:                                errno = EMSGSIZE;
                    358:                                return (-1);
                    359:                        }
                    360:                        break;
                    361: 
                    362:                default:
                    363:                        errno = EMSGSIZE;
                    364:                        return (-1);                    /* flag error */
                    365:                }
                    366:        }
                    367:        *dstp = '\0';
                    368:        if (len < 0)
                    369:                len = srcp - src;
                    370:        return (len);
                    371: }
                    372: 
                    373: /*
                    374:  * ns_name_pack(src, dst, dstsiz, dnptrs, lastdnptr)
                    375:  *     Pack domain name 'domain' into 'comp_dn'.
                    376:  * return:
                    377:  *     Size of the compressed name, or -1.
                    378:  * notes:
                    379:  *     'dnptrs' is an array of pointers to previous compressed names.
                    380:  *     dnptrs[0] is a pointer to the beginning of the message. The array
                    381:  *     ends with NULL.
                    382:  *     'lastdnptr' is a pointer to the end of the array pointed to
                    383:  *     by 'dnptrs'.
                    384:  * Side effects:
                    385:  *     The list of pointers in dnptrs is updated for labels inserted into
                    386:  *     the message as we compress the name.  If 'dnptr' is NULL, we don't
                    387:  *     try to compress names. If 'lastdnptr' is NULL, we don't update the
                    388:  *     list.
                    389:  */
                    390: int
                    391: ns_name_pack(const u_char *src, u_char *dst, unsigned dstsiz,
                    392:             const u_char **dnptrs, const u_char **lastdnptr)
                    393: {
                    394:        u_char *dstp;
                    395:        const u_char **cpp, **lpp, *eob, *msg;
                    396:        const u_char *srcp;
                    397:        unsigned n;
                    398:        int l;
                    399: 
                    400:        srcp = src;
                    401:        dstp = dst;
                    402:        eob = dstp + dstsiz;
                    403:        lpp = cpp = NULL;
                    404:        if (dnptrs != NULL) {
                    405:                if ((msg = *dnptrs++) != NULL) {
                    406:                        for (cpp = dnptrs; *cpp != NULL; cpp++)
                    407:                                (void)NULL;
                    408:                        lpp = cpp;      /* end of list to search */
                    409:                }
                    410:        } else
                    411:                msg = NULL;
                    412: 
                    413:        /* make sure the domain we are about to add is legal */
                    414:        l = 0;
                    415:        do {
                    416:                n = *srcp;
                    417:                if ((n & NS_CMPRSFLGS) != 0) {
                    418:                        errno = EMSGSIZE;
                    419:                        return (-1);
                    420:                }
                    421:                l += n + 1;
                    422:                if (l > MAXCDNAME) {
                    423:                        errno = EMSGSIZE;
                    424:                        return (-1);
                    425:                }
                    426:                srcp += n + 1;
                    427:        } while (n != 0);
                    428: 
                    429:        /* from here on we need to reset compression pointer array on error */
                    430:        srcp = src;
                    431:        do {
                    432:                /* Look to see if we can use pointers. */
                    433:                n = *srcp;
                    434:                if (n != 0 && msg != NULL) {
                    435:                        l = dn_find(srcp, msg, (const u_char * const *)dnptrs,
                    436:                                    (const u_char * const *)lpp);
                    437:                        if (l >= 0) {
                    438:                                if (dstp + 1 >= eob) {
                    439:                                        goto cleanup;
                    440:                                }
                    441:                                *dstp++ = (l >> 8) | NS_CMPRSFLGS;
                    442:                                *dstp++ = l % 256;
                    443:                                return (dstp - dst);
                    444:                        }
                    445:                        /* Not found, save it. */
                    446:                        if (lastdnptr != NULL && cpp < lastdnptr - 1 &&
                    447:                            (dstp - msg) < 0x4000) {
                    448:                                *cpp++ = dstp;
                    449:                                *cpp = NULL;
                    450:                        }
                    451:                }
                    452:                /* copy label to buffer */
                    453:                if (n & NS_CMPRSFLGS) {         /* Should not happen. */
                    454:                        goto cleanup;
                    455:                }
                    456:                if (dstp + 1 + n >= eob) {
                    457:                        goto cleanup;
                    458:                }
                    459:                memcpy(dstp, srcp, n + 1);
                    460:                srcp += n + 1;
                    461:                dstp += n + 1;
                    462:        } while (n != 0);
                    463: 
                    464:        if (dstp > eob) {
                    465: cleanup:
                    466:                if (msg != NULL)
                    467:                        *lpp = NULL;
                    468:                errno = EMSGSIZE;
                    469:                return (-1);
                    470:        } 
                    471:        return (dstp - dst);
                    472: }
                    473: 
                    474: /*
                    475:  * ns_name_uncompress(msg, eom, src, dst, dstsiz)
                    476:  *     Expand compressed domain name to presentation format.
                    477:  * return:
                    478:  *     Number of bytes read out of `src', or -1 (with errno set).
                    479:  * note:
                    480:  *     Root domain returns as "." not "".
                    481:  */
                    482: int
                    483: ns_name_uncompress(const u_char *msg, const u_char *eom, const u_char *src,
                    484:                   char *dst, size_t dstsiz)
                    485: {
                    486:        u_char tmp[NS_MAXCDNAME];
                    487:        int n;
                    488:        
                    489:        if ((n = ns_name_unpack(msg, eom, src, tmp, sizeof tmp)) == -1)
                    490:                return (-1);
                    491:        if (ns_name_ntop(tmp, dst, dstsiz) == -1)
                    492:                return (-1);
                    493:        return (n);
                    494: }
                    495: 
                    496: /*
                    497:  * ns_name_compress(src, dst, dstsiz, dnptrs, lastdnptr)
                    498:  *     Compress a domain name into wire format, using compression pointers.
                    499:  * return:
                    500:  *     Number of bytes consumed in `dst' or -1 (with errno set).
                    501:  * notes:
                    502:  *     'dnptrs' is an array of pointers to previous compressed names.
                    503:  *     dnptrs[0] is a pointer to the beginning of the message.
                    504:  *     The list ends with NULL.  'lastdnptr' is a pointer to the end of the
                    505:  *     array pointed to by 'dnptrs'. Side effect is to update the list of
                    506:  *     pointers for labels inserted into the message as we compress the name.
                    507:  *     If 'dnptr' is NULL, we don't try to compress names. If 'lastdnptr'
                    508:  *     is NULL, we don't update the list.
                    509:  */
                    510: int
                    511: ns_name_compress(const char *src, u_char *dst, size_t dstsiz,
                    512:                 const u_char **dnptrs, const u_char **lastdnptr)
                    513: {
                    514:        u_char tmp[NS_MAXCDNAME];
                    515: 
                    516:        if (ns_name_pton(src, tmp, sizeof tmp) == -1)
                    517:                return (-1);
                    518:        return (ns_name_pack(tmp, dst, dstsiz, dnptrs, lastdnptr));
                    519: }
                    520: 
                    521: /*
                    522:  * ns_name_skip(ptrptr, eom)
                    523:  *     Advance *ptrptr to skip over the compressed name it points at.
                    524:  * return:
                    525:  *     0 on success, -1 (with errno set) on failure.
                    526:  */
                    527: int
                    528: ns_name_skip(const u_char **ptrptr, const u_char *eom) {
                    529:        const u_char *cp;
                    530:        u_int n;
                    531: 
                    532:        cp = *ptrptr;
                    533:        while (cp < eom && (n = *cp++) != 0) {
                    534:                /* Check for indirection. */
                    535:                switch (n & NS_CMPRSFLGS) {
                    536:                case 0:                 /* normal case, n == len */
                    537:                        cp += n;
                    538:                        continue;
                    539:                case NS_CMPRSFLGS:      /* indirection */
                    540:                        cp++;
                    541:                        break;
                    542:                default:                /* illegal type */
                    543:                        errno = EMSGSIZE;
                    544:                        return (-1);
                    545:                }
                    546:                break;
                    547:        }
                    548:        if (cp > eom) {
                    549:                errno = EMSGSIZE;
                    550:                return (-1);
                    551:        }
                    552:        *ptrptr = cp;
                    553:        return (0);
                    554: }
                    555: 
                    556: /* Private. */
                    557: 
                    558: /*
                    559:  * special(ch)
                    560:  *     Thinking in noninternationalized USASCII (per the DNS spec),
                    561:  *     is this characted special ("in need of quoting") ?
                    562:  * return:
                    563:  *     boolean.
                    564:  */
                    565: static int
                    566: special(int ch) {
                    567:        switch (ch) {
                    568:        case 0x22: /* '"' */
                    569:        case 0x2E: /* '.' */
                    570:        case 0x3B: /* ';' */
                    571:        case 0x5C: /* '\\' */
                    572:        /* Special modifiers in zone files. */
                    573:        case 0x40: /* '@' */
                    574:        case 0x24: /* '$' */
                    575:                return (1);
                    576:        default:
                    577:                return (0);
                    578:        }
                    579: }
                    580: 
                    581: /*
                    582:  * printable(ch)
                    583:  *     Thinking in noninternationalized USASCII (per the DNS spec),
                    584:  *     is this character visible and not a space when printed ?
                    585:  * return:
                    586:  *     boolean.
                    587:  */
                    588: static int
                    589: printable(int ch) {
                    590:        return (ch > 0x20 && ch < 0x7f);
                    591: }
                    592: 
                    593: /*
                    594:  *     Thinking in noninternationalized USASCII (per the DNS spec),
                    595:  *     convert this character to lower case if it's upper case.
                    596:  */
                    597: static int
                    598: mklower(int ch) {
                    599:        if (ch >= 0x41 && ch <= 0x5A)
                    600:                return (ch + 0x20);
                    601:        return (ch);
                    602: }
                    603: 
                    604: /*
                    605:  * dn_find(domain, msg, dnptrs, lastdnptr)
                    606:  *     Search for the counted-label name in an array of compressed names.
                    607:  * return:
                    608:  *     offset from msg if found, or -1.
                    609:  * notes:
                    610:  *     dnptrs is the pointer to the first name on the list,
                    611:  *     not the pointer to the start of the message.
                    612:  */
                    613: static int
                    614: dn_find(const u_char *domain, const u_char *msg,
                    615:        const u_char * const *dnptrs,
                    616:        const u_char * const *lastdnptr)
                    617: {
                    618:        const u_char *dn, *cp, *sp;
                    619:        const u_char * const *cpp;
                    620:        u_int n;
                    621: 
                    622:        for (cpp = dnptrs; cpp < lastdnptr; cpp++) {
                    623:                dn = domain;
                    624:                sp = cp = *cpp;
                    625:                while ((n = *cp++) != 0) {
                    626:                        /*
                    627:                         * check for indirection
                    628:                         */
                    629:                        switch (n & NS_CMPRSFLGS) {
                    630:                        case 0:                 /* normal case, n == len */
                    631:                                if (n != *dn++)
                    632:                                        goto next;
                    633:                                for ((void)NULL; n > 0; n--)
                    634:                                        if (mklower(*dn++) != mklower(*cp++))
                    635:                                                goto next;
                    636:                                /* Is next root for both ? */
                    637:                                if (*dn == '\0' && *cp == '\0')
                    638:                                        return (sp - msg);
                    639:                                if (*dn)
                    640:                                        continue;
                    641:                                goto next;
                    642: 
                    643:                        case NS_CMPRSFLGS:      /* indirection */
                    644:                                cp = msg + (((n & 0x3f) << 8) | *cp);
                    645:                                break;
                    646: 
                    647:                        default:        /* illegal type */
                    648:                                errno = EMSGSIZE;
                    649:                                return (-1);
                    650:                        }
                    651:                }
                    652:  next: ;
                    653:        }
                    654:        errno = ENOENT;
                    655:        return (-1);
                    656: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>