00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #ifndef lint
00019 static const char rcsid[] = "$Id: ns_name.c,v 1.3.2.4 2003/07/02 04:10:27 marka Exp $";
00020 #endif
00021
00022
00023 #include "config.h"
00024
00025 #ifdef STDC_HEADERS
00026 # include <stdio.h>
00027 #endif
00028
00029 #include <sys/types.h>
00030
00031 #include <netinet/in.h>
00032 #include "arpa_nameser.h"
00033
00034 #include <errno.h>
00035
00036 #ifdef HAVE_STRING_H
00037 # include <string.h>
00038 #else
00039 # ifdef HAVE_STRINGS_H
00040 # include <strings.h>
00041 # endif
00042 #endif
00043
00044 #include <ctype.h>
00045 #include <stdlib.h>
00046 #include <limits.h>
00047
00048
00049
00050 #ifdef SPRINTF_CHAR
00051 # define SPRINTF(x) strlen(sprintfx)
00052 #else
00053 # define SPRINTF(x) ((size_t)sprintf x)
00054 #endif
00055
00056 #define NS_TYPE_ELT 0x40
00057 #define DNS_LABELTYPE_BITSTRING 0x41
00058
00059
00060
00061 static const char digits[] = "0123456789";
00062
00063 static const char digitvalue[256] = {
00064 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
00065 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
00066 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
00067 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -1, -1, -1, -1, -1,
00068 -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1,
00069 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
00070 -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1,
00071 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
00072 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
00073 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
00074 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
00075 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
00076 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
00077 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
00078 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
00079 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
00080 };
00081
00082
00083
00084 static int special(int);
00085 static int printable(int);
00086 static int dn_find(const u_char *, const u_char *,
00087 const u_char * const *,
00088 const u_char * const *);
00089 static int encode_bitsring(const char **, const char *,
00090 char **, char **, const char *);
00091 static int labellen(const u_char *);
00092 static int decode_bitstring(const char **, char *, const char *);
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105 int
00106 ns_name_ntop(const u_char *src, char *dst, size_t dstsiz)
00107 {
00108 const u_char *cp;
00109 char *dn, *eom;
00110 u_char c;
00111 u_int n;
00112 int l;
00113
00114 cp = src;
00115 dn = dst;
00116 eom = dst + dstsiz;
00117
00118 while ((n = *cp++) != 0) {
00119 if ((n & NS_CMPRSFLGS) == NS_CMPRSFLGS) {
00120
00121 errno = EMSGSIZE;
00122 return (-1);
00123 }
00124 if (dn != dst) {
00125 if (dn >= eom) {
00126 errno = EMSGSIZE;
00127 return (-1);
00128 }
00129 *dn++ = '.';
00130 }
00131 if ((l = labellen(cp - 1)) < 0) {
00132 errno = EMSGSIZE;
00133 return(-1);
00134 }
00135 if (dn + l >= eom) {
00136 errno = EMSGSIZE;
00137 return (-1);
00138 }
00139 if ((n & NS_CMPRSFLGS) == NS_TYPE_ELT) {
00140 int m;
00141
00142 if (n != DNS_LABELTYPE_BITSTRING) {
00143
00144 errno = EINVAL;
00145 return(-1);
00146 }
00147 if ((m = decode_bitstring((const char **)&cp, dn, eom)) < 0)
00148 {
00149 errno = EMSGSIZE;
00150 return(-1);
00151 }
00152 dn += m;
00153 continue;
00154 }
00155 for ((void)NULL; l > 0; l--) {
00156 c = *cp++;
00157 if (special(c)) {
00158 if (dn + 1 >= eom) {
00159 errno = EMSGSIZE;
00160 return (-1);
00161 }
00162 *dn++ = '\\';
00163 *dn++ = (char)c;
00164 } else if (!printable(c)) {
00165 if (dn + 3 >= eom) {
00166 errno = EMSGSIZE;
00167 return (-1);
00168 }
00169 *dn++ = '\\';
00170 *dn++ = digits[c / 100];
00171 *dn++ = digits[(c % 100) / 10];
00172 *dn++ = digits[c % 10];
00173 } else {
00174 if (dn >= eom) {
00175 errno = EMSGSIZE;
00176 return (-1);
00177 }
00178 *dn++ = (char)c;
00179 }
00180 }
00181 }
00182 if (dn == dst) {
00183 if (dn >= eom) {
00184 errno = EMSGSIZE;
00185 return (-1);
00186 }
00187 *dn++ = '.';
00188 }
00189 if (dn >= eom) {
00190 errno = EMSGSIZE;
00191 return (-1);
00192 }
00193 *dn++ = '\0';
00194 return (dn - dst);
00195 }
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208 int
00209 ns_name_pton(const char *src, u_char *dst, size_t dstsiz)
00210 {
00211 u_char *label, *bp, *eom;
00212 int c, n, escaped, e = 0;
00213 char *cp;
00214
00215 escaped = 0;
00216 bp = dst;
00217 eom = dst + dstsiz;
00218 label = bp++;
00219
00220 while ((c = *src++) != 0) {
00221 if (escaped) {
00222 if (c == '[') {
00223 if ((cp = strchr(src, ']')) == NULL) {
00224 errno = EINVAL;
00225 return(-1);
00226 }
00227 if ((e = encode_bitsring(&src,
00228 cp + 2,
00229 (char **)&label,
00230 (char **)&bp,
00231 (const char *)eom))
00232 != 0) {
00233 errno = e;
00234 return(-1);
00235 }
00236 escaped = 0;
00237 label = bp++;
00238 if ((c = *src++) == 0)
00239 goto done;
00240 else if (c != '.') {
00241 errno = EINVAL;
00242 return(-1);
00243 }
00244 continue;
00245 }
00246 else if ((cp = strchr(digits, c)) != NULL) {
00247 n = (cp - digits) * 100;
00248 if ((c = *src++) == 0 ||
00249 (cp = strchr(digits, c)) == NULL) {
00250 errno = EMSGSIZE;
00251 return (-1);
00252 }
00253 n += (cp - digits) * 10;
00254 if ((c = *src++) == 0 ||
00255 (cp = strchr(digits, c)) == NULL) {
00256 errno = EMSGSIZE;
00257 return (-1);
00258 }
00259 n += (cp - digits);
00260 if (n > 255) {
00261 errno = EMSGSIZE;
00262 return (-1);
00263 }
00264 c = n;
00265 }
00266 escaped = 0;
00267 } else if (c == '\\') {
00268 escaped = 1;
00269 continue;
00270 } else if (c == '.') {
00271 c = (bp - label - 1);
00272 if ((c & NS_CMPRSFLGS) != 0) {
00273 errno = EMSGSIZE;
00274 return (-1);
00275 }
00276 if (label >= eom) {
00277 errno = EMSGSIZE;
00278 return (-1);
00279 }
00280 *label = c;
00281
00282 if (*src == '\0') {
00283 if (c != 0) {
00284 if (bp >= eom) {
00285 errno = EMSGSIZE;
00286 return (-1);
00287 }
00288 *bp++ = '\0';
00289 }
00290 if ((bp - dst) > NS_MAXCDNAME) {
00291 errno = EMSGSIZE;
00292 return (-1);
00293 }
00294 return (1);
00295 }
00296 if (c == 0 || *src == '.') {
00297 errno = EMSGSIZE;
00298 return (-1);
00299 }
00300 label = bp++;
00301 continue;
00302 }
00303 if (bp >= eom) {
00304 errno = EMSGSIZE;
00305 return (-1);
00306 }
00307 *bp++ = (u_char)c;
00308 }
00309 c = (bp - label - 1);
00310 if ((c & NS_CMPRSFLGS) != 0) {
00311 errno = EMSGSIZE;
00312 return (-1);
00313 }
00314 done:
00315 if (label >= eom) {
00316 errno = EMSGSIZE;
00317 return (-1);
00318 }
00319 *label = c;
00320 if (c != 0) {
00321 if (bp >= eom) {
00322 errno = EMSGSIZE;
00323 return (-1);
00324 }
00325 *bp++ = 0;
00326 }
00327 if ((bp - dst) > NS_MAXCDNAME) {
00328 errno = EMSGSIZE;
00329 return (-1);
00330 }
00331 return (0);
00332 }
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343 int
00344 ns_name_ntol(const u_char *src, u_char *dst, size_t dstsiz)
00345 {
00346 const u_char *cp;
00347 u_char *dn, *eom;
00348 u_char c;
00349 u_int n;
00350 int l;
00351
00352 cp = src;
00353 dn = dst;
00354 eom = dst + dstsiz;
00355
00356 if (dn >= eom) {
00357 errno = EMSGSIZE;
00358 return (-1);
00359 }
00360 while ((n = *cp++) != 0) {
00361 if ((n & NS_CMPRSFLGS) == NS_CMPRSFLGS) {
00362
00363 errno = EMSGSIZE;
00364 return (-1);
00365 }
00366 *dn++ = n;
00367 if ((l = labellen(cp - 1)) < 0) {
00368 errno = EMSGSIZE;
00369 return (-1);
00370 }
00371 if (dn + l >= eom) {
00372 errno = EMSGSIZE;
00373 return (-1);
00374 }
00375 for ((void)NULL; l > 0; l--) {
00376 c = *cp++;
00377 if (isupper(c))
00378 *dn++ = tolower(c);
00379 else
00380 *dn++ = c;
00381 }
00382 }
00383 *dn++ = '\0';
00384 return (dn - dst);
00385 }
00386
00387
00388
00389
00390
00391
00392
00393 int
00394 ns_name_unpack(const u_char *msg, const u_char *eom, const u_char *src,
00395 u_char *dst, size_t dstsiz)
00396 {
00397 const u_char *srcp, *dstlim;
00398 u_char *dstp;
00399 int n, len, checked, l;
00400
00401 len = -1;
00402 checked = 0;
00403 dstp = dst;
00404 srcp = src;
00405 dstlim = dst + dstsiz;
00406 if (srcp < msg || srcp >= eom) {
00407 errno = EMSGSIZE;
00408 return (-1);
00409 }
00410
00411 while ((n = *srcp++) != 0) {
00412
00413 switch (n & NS_CMPRSFLGS) {
00414 case 0:
00415 case NS_TYPE_ELT:
00416
00417 if ((l = labellen(srcp - 1)) < 0) {
00418 errno = EMSGSIZE;
00419 return(-1);
00420 }
00421 if (dstp + l + 1 >= dstlim || srcp + l >= eom) {
00422 errno = EMSGSIZE;
00423 return (-1);
00424 }
00425 checked += l + 1;
00426 *dstp++ = n;
00427 memcpy(dstp, srcp, l);
00428 dstp += l;
00429 srcp += l;
00430 break;
00431
00432 case NS_CMPRSFLGS:
00433 if (srcp >= eom) {
00434 errno = EMSGSIZE;
00435 return (-1);
00436 }
00437 if (len < 0)
00438 len = srcp - src + 1;
00439 srcp = msg + (((n & 0x3f) << 8) | (*srcp & 0xff));
00440 if (srcp < msg || srcp >= eom) {
00441 errno = EMSGSIZE;
00442 return (-1);
00443 }
00444 checked += 2;
00445
00446
00447
00448
00449
00450 if (checked >= eom - msg) {
00451 errno = EMSGSIZE;
00452 return (-1);
00453 }
00454 break;
00455
00456 default:
00457 errno = EMSGSIZE;
00458 return (-1);
00459 }
00460 }
00461 *dstp = '\0';
00462 if (len < 0)
00463 len = srcp - src;
00464 return (len);
00465 }
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484 int
00485 ns_name_pack(const u_char *src, u_char *dst, int dstsiz,
00486 const u_char **dnptrs, const u_char **lastdnptr)
00487 {
00488 u_char *dstp;
00489 const u_char **cpp, **lpp, *eob, *msg;
00490 const u_char *srcp;
00491 int n, l, first = 1;
00492
00493 srcp = src;
00494 dstp = dst;
00495 eob = dstp + dstsiz;
00496 lpp = cpp = NULL;
00497 if (dnptrs != NULL) {
00498 if ((msg = *dnptrs++) != NULL) {
00499 for (cpp = dnptrs; *cpp != NULL; cpp++)
00500 (void)NULL;
00501 lpp = cpp;
00502 }
00503 } else
00504 msg = NULL;
00505
00506
00507 l = 0;
00508 do {
00509 int l0;
00510
00511 n = *srcp;
00512 if ((n & NS_CMPRSFLGS) == NS_CMPRSFLGS) {
00513 errno = EMSGSIZE;
00514 return (-1);
00515 }
00516 if ((l0 = labellen(srcp)) < 0) {
00517 errno = EINVAL;
00518 return(-1);
00519 }
00520 l += l0 + 1;
00521 if (l > NS_MAXCDNAME) {
00522 errno = EMSGSIZE;
00523 return (-1);
00524 }
00525 srcp += l0 + 1;
00526 } while (n != 0);
00527
00528
00529 srcp = src;
00530 do {
00531
00532 n = *srcp;
00533 if (n != 0 && msg != NULL) {
00534 l = dn_find(srcp, msg, (const u_char * const *)dnptrs,
00535 (const u_char * const *)lpp);
00536 if (l >= 0) {
00537 if (dstp + 1 >= eob) {
00538 goto cleanup;
00539 }
00540 *dstp++ = (l >> 8) | NS_CMPRSFLGS;
00541 *dstp++ = l % 256;
00542 return (dstp - dst);
00543 }
00544
00545 if (lastdnptr != NULL && cpp < lastdnptr - 1 &&
00546 (dstp - msg) < 0x4000 && first) {
00547 *cpp++ = dstp;
00548 *cpp = NULL;
00549 first = 0;
00550 }
00551 }
00552
00553 if ((n & NS_CMPRSFLGS) == NS_CMPRSFLGS) {
00554
00555 goto cleanup;
00556 }
00557 n = labellen(srcp);
00558 if (dstp + 1 + n >= eob) {
00559 goto cleanup;
00560 }
00561 memcpy(dstp, srcp, n + 1);
00562 srcp += n + 1;
00563 dstp += n + 1;
00564 } while (n != 0);
00565
00566 if (dstp > eob) {
00567 cleanup:
00568 if (msg != NULL)
00569 *lpp = NULL;
00570 errno = EMSGSIZE;
00571 return (-1);
00572 }
00573 return (dstp - dst);
00574 }
00575
00576
00577
00578
00579
00580
00581
00582
00583
00584 int
00585 ns_name_uncompress(const u_char *msg, const u_char *eom, const u_char *src,
00586 char *dst, size_t dstsiz)
00587 {
00588 u_char tmp[NS_MAXCDNAME];
00589 int n;
00590
00591 if ((n = ns_name_unpack(msg, eom, src, tmp, sizeof tmp)) == -1)
00592 return (-1);
00593 if (ns_name_ntop(tmp, dst, dstsiz) == -1)
00594 return (-1);
00595 return (n);
00596 }
00597
00598
00599
00600
00601
00602
00603
00604
00605
00606
00607
00608
00609
00610
00611
00612 int
00613 ns_name_compress(const char *src, u_char *dst, size_t dstsiz,
00614 const u_char **dnptrs, const u_char **lastdnptr)
00615 {
00616 u_char tmp[NS_MAXCDNAME];
00617
00618 if (ns_name_pton(src, tmp, sizeof tmp) == -1)
00619 return (-1);
00620 return (ns_name_pack(tmp, dst, dstsiz, dnptrs, lastdnptr));
00621 }
00622
00623
00624
00625
00626
00627 void
00628 ns_name_rollback(const u_char *src, const u_char **dnptrs,
00629 const u_char **lastdnptr)
00630 {
00631 while (dnptrs < lastdnptr && *dnptrs != NULL) {
00632 if (*dnptrs >= src) {
00633 *dnptrs = NULL;
00634 break;
00635 }
00636 dnptrs++;
00637 }
00638 }
00639
00640
00641
00642
00643
00644
00645
00646 int
00647 ns_name_skip(const u_char **ptrptr, const u_char *eom)
00648 {
00649 const u_char *cp;
00650 u_int n;
00651 int l;
00652
00653 cp = *ptrptr;
00654 while (cp < eom && (n = *cp++) != 0) {
00655
00656 switch (n & NS_CMPRSFLGS) {
00657 case 0:
00658 cp += n;
00659 continue;
00660 case NS_TYPE_ELT:
00661 if ((l = labellen(cp - 1)) < 0) {
00662 errno = EMSGSIZE;
00663 return(-1);
00664 }
00665 cp += l;
00666 continue;
00667 case NS_CMPRSFLGS:
00668 cp++;
00669 break;
00670 default:
00671 errno = EMSGSIZE;
00672 return (-1);
00673 }
00674 break;
00675 }
00676 if (cp > eom) {
00677 errno = EMSGSIZE;
00678 return (-1);
00679 }
00680 *ptrptr = cp;
00681 return (0);
00682 }
00683
00684
00685
00686
00687
00688
00689
00690
00691
00692
00693 static int
00694 special(int ch) {
00695 switch (ch) {
00696 case 0x22:
00697 case 0x2E:
00698 case 0x3B:
00699 case 0x5C:
00700 case 0x28:
00701 case 0x29:
00702
00703 case 0x40:
00704 case 0x24:
00705 return (1);
00706 default:
00707 return (0);
00708 }
00709 }
00710
00711
00712
00713
00714
00715
00716
00717
00718 static int
00719 printable(int ch) {
00720 return (ch > 0x20 && ch < 0x7f);
00721 }
00722
00723
00724
00725
00726
00727 static int
00728 mklower(int ch) {
00729 if (ch >= 0x41 && ch <= 0x5A)
00730 return (ch + 0x20);
00731 return (ch);
00732 }
00733
00734
00735
00736
00737
00738
00739
00740
00741
00742
00743 static int
00744 dn_find(const u_char *domain, const u_char *msg,
00745 const u_char * const *dnptrs,
00746 const u_char * const *lastdnptr)
00747 {
00748 const u_char *dn, *cp, *sp;
00749 const u_char * const *cpp;
00750 u_int n;
00751
00752 for (cpp = dnptrs; cpp < lastdnptr; cpp++) {
00753 sp = *cpp;
00754
00755
00756
00757
00758
00759
00760 while (*sp != 0 && (*sp & NS_CMPRSFLGS) == 0 &&
00761 (sp - msg) < 0x4000) {
00762 dn = domain;
00763 cp = sp;
00764 while ((n = *cp++) != 0) {
00765
00766
00767
00768 switch (n & NS_CMPRSFLGS) {
00769 case 0:
00770 n = labellen(cp - 1);
00771
00772 if (n != *dn++)
00773 goto next;
00774
00775 for ((void)NULL; n > 0; n--)
00776 if (mklower(*dn++) !=
00777 mklower(*cp++))
00778 goto next;
00779
00780 if (*dn == '\0' && *cp == '\0')
00781 return (sp - msg);
00782 if (*dn)
00783 continue;
00784 goto next;
00785 case NS_CMPRSFLGS:
00786 cp = msg + (((n & 0x3f) << 8) | *cp);
00787 break;
00788
00789 default:
00790 errno = EMSGSIZE;
00791 return (-1);
00792 }
00793 }
00794 next: ;
00795 sp += *sp + 1;
00796 }
00797 }
00798 errno = ENOENT;
00799 return (-1);
00800 }
00801
00802 static int
00803 decode_bitstring(const char **cpp, char *dn, const char *eom)
00804 {
00805 const char *cp = *cpp;
00806 char *beg = dn, tc;
00807 int b, blen, plen, i;
00808
00809 if ((blen = (*cp & 0xff)) == 0)
00810 blen = 256;
00811 plen = (blen + 3) / 4;
00812 plen += sizeof("\\[x/]") + (blen > 99 ? 3 : (blen > 9) ? 2 : 1);
00813 if (dn + plen >= eom)
00814 return(-1);
00815
00816 cp++;
00817 i = SPRINTF((dn, "\\[x"));
00818 if (i < 0)
00819 return (-1);
00820 dn += i;
00821 for (b = blen; b > 7; b -= 8, cp++) {
00822 i = SPRINTF((dn, "%02x", *cp & 0xff));
00823 if (i < 0)
00824 return (-1);
00825 dn += i;
00826 }
00827 if (b > 4) {
00828 tc = *cp++;
00829 i = SPRINTF((dn, "%02x", tc & (0xff << (8 - b))));
00830 if (i < 0)
00831 return (-1);
00832 dn += i;
00833 } else if (b > 0) {
00834 tc = *cp++;
00835 i = SPRINTF((dn, "%1x",
00836 ((tc >> 4) & 0x0f) & (0x0f << (4 - b))));
00837 if (i < 0)
00838 return (-1);
00839 dn += i;
00840 }
00841 i = SPRINTF((dn, "/%d]", blen));
00842 if (i < 0)
00843 return (-1);
00844 dn += i;
00845
00846 *cpp = cp;
00847 return(dn - beg);
00848 }
00849
00850 static int
00851 encode_bitsring(const char **bp, const char *end, char **labelp,
00852 char ** dst, const char *eom)
00853 {
00854 int afterslash = 0;
00855 const char *cp = *bp;
00856 char *tp, c;
00857 const char *beg_blen;
00858 char *end_blen = NULL;
00859 int value = 0, count = 0, tbcount = 0, blen = 0;
00860
00861 beg_blen = end_blen = NULL;
00862
00863
00864 if (end - cp < 2)
00865 return(EINVAL);
00866
00867
00868 if (*cp++ != 'x')
00869 return(EINVAL);
00870 if (!isxdigit((*cp) & 0xff))
00871 return(EINVAL);
00872
00873 for (tp = *dst + 1; cp < end && tp < eom; cp++) {
00874 switch((c = *cp)) {
00875 case ']':
00876 if (afterslash) {
00877 if (beg_blen == NULL)
00878 return(EINVAL);
00879 blen = (int)strtol(beg_blen, &end_blen, 10);
00880 if (*end_blen != ']')
00881 return(EINVAL);
00882 }
00883 if (count)
00884 *tp++ = ((value << 4) & 0xff);
00885 cp++;
00886 goto done;
00887 case '/':
00888 afterslash = 1;
00889 break;
00890 default:
00891 if (afterslash) {
00892 if (!isdigit(c&0xff))
00893 return(EINVAL);
00894 if (beg_blen == NULL) {
00895
00896 if (c == '0') {
00897
00898 return(EINVAL);
00899 }
00900 beg_blen = cp;
00901 }
00902 } else {
00903 if (!isxdigit(c&0xff))
00904 return(EINVAL);
00905 value <<= 4;
00906 value += digitvalue[(int)c];
00907 count += 4;
00908 tbcount += 4;
00909 if (tbcount > 256)
00910 return(EINVAL);
00911 if (count == 8) {
00912 *tp++ = value;
00913 count = 0;
00914 }
00915 }
00916 break;
00917 }
00918 }
00919 done:
00920 if (cp >= end || tp >= eom)
00921 return(EMSGSIZE);
00922
00923
00924
00925
00926
00927
00928
00929
00930
00931 if (blen > 0) {
00932 int traillen;
00933
00934 if (((blen + 3) & ~3) != tbcount)
00935 return(EINVAL);
00936 traillen = tbcount - blen;
00937 if (((value << (8 - traillen)) & 0xff) != 0)
00938 return(EINVAL);
00939 }
00940 else
00941 blen = tbcount;
00942 if (blen == 256)
00943 blen = 0;
00944
00945
00946 **labelp = DNS_LABELTYPE_BITSTRING;
00947 **dst = blen;
00948
00949 *bp = cp;
00950 *dst = tp;
00951
00952 return(0);
00953 }
00954
00955 static int
00956 labellen(const u_char *lp)
00957 {
00958 int bitlen;
00959 u_char l = *lp;
00960
00961 if ((l & NS_CMPRSFLGS) == NS_CMPRSFLGS) {
00962
00963 return(-1);
00964 }
00965
00966 if ((l & NS_CMPRSFLGS) == NS_TYPE_ELT) {
00967 if (l == DNS_LABELTYPE_BITSTRING) {
00968 if ((bitlen = *(lp + 1)) == 0)
00969 bitlen = 256;
00970 return((bitlen + 7 ) / 8 + 1);
00971 }
00972 return(-1);
00973 }
00974 return(l);
00975 }