ns_name.c (170243) | ns_name.c (269867) |
---|---|
1/* 2 * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC") 3 * Copyright (c) 1996,1999 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 18#ifndef lint | 1/* 2 * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC") 3 * Copyright (c) 1996,1999 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 18#ifndef lint |
19static const char rcsid[] = "$Id: ns_name.c,v 1.8.18.2 2005/04/27 05:01:08 sra Exp $"; | 19static const char rcsid[] = "$Id: ns_name.c,v 1.11 2009/01/23 19:59:16 each Exp $"; |
20#endif | 20#endif |
21#include <sys/cdefs.h> 22__FBSDID("$FreeBSD: head/lib/libc/nameser/ns_name.c 269867 2014-08-12 12:36:06Z ume $"); |
|
21 22#include "port_before.h" 23 24#include <sys/types.h> 25 26#include <netinet/in.h> 27#include <arpa/nameser.h> 28 --- 87 unchanged lines hidden (view full) --- 116 if (dn >= eom) { 117 errno = EMSGSIZE; 118 return (-1); 119 } 120 *dn++ = '.'; 121 } 122 if ((l = labellen(cp - 1)) < 0) { 123 errno = EMSGSIZE; /*%< XXX */ | 23 24#include "port_before.h" 25 26#include <sys/types.h> 27 28#include <netinet/in.h> 29#include <arpa/nameser.h> 30 --- 87 unchanged lines hidden (view full) --- 118 if (dn >= eom) { 119 errno = EMSGSIZE; 120 return (-1); 121 } 122 *dn++ = '.'; 123 } 124 if ((l = labellen(cp - 1)) < 0) { 125 errno = EMSGSIZE; /*%< XXX */ |
124 return(-1); | 126 return (-1); |
125 } 126 if (dn + l >= eom) { 127 errno = EMSGSIZE; 128 return (-1); 129 } 130 if ((n & NS_CMPRSFLGS) == NS_TYPE_ELT) { 131 int m; 132 133 if (n != DNS_LABELTYPE_BITSTRING) { 134 /* XXX: labellen should reject this case */ 135 errno = EINVAL; | 127 } 128 if (dn + l >= eom) { 129 errno = EMSGSIZE; 130 return (-1); 131 } 132 if ((n & NS_CMPRSFLGS) == NS_TYPE_ELT) { 133 int m; 134 135 if (n != DNS_LABELTYPE_BITSTRING) { 136 /* XXX: labellen should reject this case */ 137 errno = EINVAL; |
136 return(-1); | 138 return (-1); |
137 } 138 if ((m = decode_bitstring(&cp, dn, eom)) < 0) 139 { 140 errno = EMSGSIZE; | 139 } 140 if ((m = decode_bitstring(&cp, dn, eom)) < 0) 141 { 142 errno = EMSGSIZE; |
141 return(-1); | 143 return (-1); |
142 } 143 dn += m; 144 continue; 145 } 146 for ((void)NULL; l > 0; l--) { 147 c = *cp++; 148 if (special(c)) { 149 if (dn + 1 >= eom) { --- 42 unchanged lines hidden (view full) --- 192 * 193 *\li -1 if it fails 194 *\li 1 if string was fully qualified 195 *\li 0 is string was not fully qualified 196 * 197 * notes: 198 *\li Enforces label and domain length limits. 199 */ | 144 } 145 dn += m; 146 continue; 147 } 148 for ((void)NULL; l > 0; l--) { 149 c = *cp++; 150 if (special(c)) { 151 if (dn + 1 >= eom) { --- 42 unchanged lines hidden (view full) --- 194 * 195 *\li -1 if it fails 196 *\li 1 if string was fully qualified 197 *\li 0 is string was not fully qualified 198 * 199 * notes: 200 *\li Enforces label and domain length limits. 201 */ |
202int 203ns_name_pton(const char *src, u_char *dst, size_t dstsiz) { 204 return (ns_name_pton2(src, dst, dstsiz, NULL)); 205} |
|
200 | 206 |
207/* 208 * ns_name_pton2(src, dst, dstsiz, *dstlen) 209 * Convert a ascii string into an encoded domain name as per RFC1035. 210 * return: 211 * -1 if it fails 212 * 1 if string was fully qualified 213 * 0 is string was not fully qualified 214 * side effects: 215 * fills in *dstlen (if non-NULL) 216 * notes: 217 * Enforces label and domain length limits. 218 */ |
|
201int | 219int |
202ns_name_pton(const char *src, u_char *dst, size_t dstsiz) 203{ | 220ns_name_pton2(const char *src, u_char *dst, size_t dstsiz, size_t *dstlen) { |
204 u_char *label, *bp, *eom; 205 int c, n, escaped, e = 0; 206 char *cp; 207 208 escaped = 0; 209 bp = dst; 210 eom = dst + dstsiz; 211 label = bp++; 212 213 while ((c = *src++) != 0) { 214 if (escaped) { 215 if (c == '[') { /*%< start a bit string label */ 216 if ((cp = strchr(src, ']')) == NULL) { 217 errno = EINVAL; /*%< ??? */ | 221 u_char *label, *bp, *eom; 222 int c, n, escaped, e = 0; 223 char *cp; 224 225 escaped = 0; 226 bp = dst; 227 eom = dst + dstsiz; 228 label = bp++; 229 230 while ((c = *src++) != 0) { 231 if (escaped) { 232 if (c == '[') { /*%< start a bit string label */ 233 if ((cp = strchr(src, ']')) == NULL) { 234 errno = EINVAL; /*%< ??? */ |
218 return(-1); | 235 return (-1); |
219 } 220 if ((e = encode_bitsring(&src, cp + 2, 221 &label, &bp, eom)) 222 != 0) { 223 errno = e; | 236 } 237 if ((e = encode_bitsring(&src, cp + 2, 238 &label, &bp, eom)) 239 != 0) { 240 errno = e; |
224 return(-1); | 241 return (-1); |
225 } 226 escaped = 0; 227 label = bp++; 228 if ((c = *src++) == 0) 229 goto done; 230 else if (c != '.') { 231 errno = EINVAL; | 242 } 243 escaped = 0; 244 label = bp++; 245 if ((c = *src++) == 0) 246 goto done; 247 else if (c != '.') { 248 errno = EINVAL; |
232 return(-1); | 249 return (-1); |
233 } 234 continue; 235 } 236 else if ((cp = strchr(digits, c)) != NULL) { 237 n = (cp - digits) * 100; 238 if ((c = *src++) == 0 || 239 (cp = strchr(digits, c)) == NULL) { 240 errno = EMSGSIZE; --- 35 unchanged lines hidden (view full) --- 276 return (-1); 277 } 278 *bp++ = '\0'; 279 } 280 if ((bp - dst) > MAXCDNAME) { 281 errno = EMSGSIZE; 282 return (-1); 283 } | 250 } 251 continue; 252 } 253 else if ((cp = strchr(digits, c)) != NULL) { 254 n = (cp - digits) * 100; 255 if ((c = *src++) == 0 || 256 (cp = strchr(digits, c)) == NULL) { 257 errno = EMSGSIZE; --- 35 unchanged lines hidden (view full) --- 293 return (-1); 294 } 295 *bp++ = '\0'; 296 } 297 if ((bp - dst) > MAXCDNAME) { 298 errno = EMSGSIZE; 299 return (-1); 300 } |
301 if (dstlen != NULL) 302 *dstlen = (bp - dst); |
|
284 return (1); 285 } 286 if (c == 0 || *src == '.') { 287 errno = EMSGSIZE; 288 return (-1); 289 } 290 label = bp++; 291 continue; --- 21 unchanged lines hidden (view full) --- 313 return (-1); 314 } 315 *bp++ = 0; 316 } 317 if ((bp - dst) > MAXCDNAME) { /*%< src too big */ 318 errno = EMSGSIZE; 319 return (-1); 320 } | 303 return (1); 304 } 305 if (c == 0 || *src == '.') { 306 errno = EMSGSIZE; 307 return (-1); 308 } 309 label = bp++; 310 continue; --- 21 unchanged lines hidden (view full) --- 332 return (-1); 333 } 334 *bp++ = 0; 335 } 336 if ((bp - dst) > MAXCDNAME) { /*%< src too big */ 337 errno = EMSGSIZE; 338 return (-1); 339 } |
340 if (dstlen != NULL) 341 *dstlen = (bp - dst); |
|
321 return (0); 322} 323 324/*% 325 * Convert a network strings labels into all lowercase. 326 * 327 * return: 328 *\li Number of bytes written to buffer, or -1 (with errno set) --- 31 unchanged lines hidden (view full) --- 360 return (-1); 361 } 362 if (dn + l >= eom) { 363 errno = EMSGSIZE; 364 return (-1); 365 } 366 for ((void)NULL; l > 0; l--) { 367 c = *cp++; | 342 return (0); 343} 344 345/*% 346 * Convert a network strings labels into all lowercase. 347 * 348 * return: 349 *\li Number of bytes written to buffer, or -1 (with errno set) --- 31 unchanged lines hidden (view full) --- 381 return (-1); 382 } 383 if (dn + l >= eom) { 384 errno = EMSGSIZE; 385 return (-1); 386 } 387 for ((void)NULL; l > 0; l--) { 388 c = *cp++; |
368 if (isupper(c)) | 389 if (isascii(c) && isupper(c)) |
369 *dn++ = tolower(c); 370 else 371 *dn++ = c; 372 } 373 } 374 *dn++ = '\0'; 375 return (dn - dst); 376} 377 378/*% 379 * Unpack a domain name from a message, source may be compressed. 380 * 381 * return: 382 *\li -1 if it fails, or consumed octets if it succeeds. 383 */ 384int 385ns_name_unpack(const u_char *msg, const u_char *eom, const u_char *src, 386 u_char *dst, size_t dstsiz) 387{ | 390 *dn++ = tolower(c); 391 else 392 *dn++ = c; 393 } 394 } 395 *dn++ = '\0'; 396 return (dn - dst); 397} 398 399/*% 400 * Unpack a domain name from a message, source may be compressed. 401 * 402 * return: 403 *\li -1 if it fails, or consumed octets if it succeeds. 404 */ 405int 406ns_name_unpack(const u_char *msg, const u_char *eom, const u_char *src, 407 u_char *dst, size_t dstsiz) 408{ |
409 return (ns_name_unpack2(msg, eom, src, dst, dstsiz, NULL)); 410} 411 412/* 413 * ns_name_unpack2(msg, eom, src, dst, dstsiz, *dstlen) 414 * Unpack a domain name from a message, source may be compressed. 415 * return: 416 * -1 if it fails, or consumed octets if it succeeds. 417 * side effect: 418 * fills in *dstlen (if non-NULL). 419 */ 420int 421ns_name_unpack2(const u_char *msg, const u_char *eom, const u_char *src, 422 u_char *dst, size_t dstsiz, size_t *dstlen) 423{ |
|
388 const u_char *srcp, *dstlim; 389 u_char *dstp; 390 int n, len, checked, l; 391 392 len = -1; 393 checked = 0; 394 dstp = dst; 395 srcp = src; --- 6 unchanged lines hidden (view full) --- 402 while ((n = *srcp++) != 0) { 403 /* Check for indirection. */ 404 switch (n & NS_CMPRSFLGS) { 405 case 0: 406 case NS_TYPE_ELT: 407 /* Limit checks. */ 408 if ((l = labellen(srcp - 1)) < 0) { 409 errno = EMSGSIZE; | 424 const u_char *srcp, *dstlim; 425 u_char *dstp; 426 int n, len, checked, l; 427 428 len = -1; 429 checked = 0; 430 dstp = dst; 431 srcp = src; --- 6 unchanged lines hidden (view full) --- 438 while ((n = *srcp++) != 0) { 439 /* Check for indirection. */ 440 switch (n & NS_CMPRSFLGS) { 441 case 0: 442 case NS_TYPE_ELT: 443 /* Limit checks. */ 444 if ((l = labellen(srcp - 1)) < 0) { 445 errno = EMSGSIZE; |
410 return(-1); | 446 return (-1); |
411 } 412 if (dstp + l + 1 >= dstlim || srcp + l >= eom) { 413 errno = EMSGSIZE; 414 return (-1); 415 } 416 checked += l + 1; 417 *dstp++ = n; 418 memcpy(dstp, srcp, l); --- 25 unchanged lines hidden (view full) --- 444 } 445 break; 446 447 default: 448 errno = EMSGSIZE; 449 return (-1); /*%< flag error */ 450 } 451 } | 447 } 448 if (dstp + l + 1 >= dstlim || srcp + l >= eom) { 449 errno = EMSGSIZE; 450 return (-1); 451 } 452 checked += l + 1; 453 *dstp++ = n; 454 memcpy(dstp, srcp, l); --- 25 unchanged lines hidden (view full) --- 480 } 481 break; 482 483 default: 484 errno = EMSGSIZE; 485 return (-1); /*%< flag error */ 486 } 487 } |
452 *dstp = '\0'; | 488 *dstp++ = 0; 489 if (dstlen != NULL) 490 *dstlen = dstp - dst; |
453 if (len < 0) 454 len = srcp - src; 455 return (len); 456} 457 458/*% 459 * Pack domain name 'domain' into 'comp_dn'. 460 * --- 42 unchanged lines hidden (view full) --- 503 504 n = *srcp; 505 if ((n & NS_CMPRSFLGS) == NS_CMPRSFLGS) { 506 errno = EMSGSIZE; 507 return (-1); 508 } 509 if ((l0 = labellen(srcp)) < 0) { 510 errno = EINVAL; | 491 if (len < 0) 492 len = srcp - src; 493 return (len); 494} 495 496/*% 497 * Pack domain name 'domain' into 'comp_dn'. 498 * --- 42 unchanged lines hidden (view full) --- 541 542 n = *srcp; 543 if ((n & NS_CMPRSFLGS) == NS_CMPRSFLGS) { 544 errno = EMSGSIZE; 545 return (-1); 546 } 547 if ((l0 = labellen(srcp)) < 0) { 548 errno = EINVAL; |
511 return(-1); | 549 return (-1); |
512 } 513 l += l0 + 1; 514 if (l > MAXCDNAME) { 515 errno = EMSGSIZE; 516 return (-1); 517 } 518 srcp += l0 + 1; 519 } while (n != 0); --- 130 unchanged lines hidden (view full) --- 650 /* Check for indirection. */ 651 switch (n & NS_CMPRSFLGS) { 652 case 0: /*%< normal case, n == len */ 653 cp += n; 654 continue; 655 case NS_TYPE_ELT: /*%< EDNS0 extended label */ 656 if ((l = labellen(cp - 1)) < 0) { 657 errno = EMSGSIZE; /*%< XXX */ | 550 } 551 l += l0 + 1; 552 if (l > MAXCDNAME) { 553 errno = EMSGSIZE; 554 return (-1); 555 } 556 srcp += l0 + 1; 557 } while (n != 0); --- 130 unchanged lines hidden (view full) --- 688 /* Check for indirection. */ 689 switch (n & NS_CMPRSFLGS) { 690 case 0: /*%< normal case, n == len */ 691 cp += n; 692 continue; 693 case NS_TYPE_ELT: /*%< EDNS0 extended label */ 694 if ((l = labellen(cp - 1)) < 0) { 695 errno = EMSGSIZE; /*%< XXX */ |
658 return(-1); | 696 return (-1); |
659 } 660 cp += l; 661 continue; 662 case NS_CMPRSFLGS: /*%< indirection */ 663 cp++; 664 break; 665 default: /*%< illegal type */ 666 errno = EMSGSIZE; --- 4 unchanged lines hidden (view full) --- 671 if (cp > eom) { 672 errno = EMSGSIZE; 673 return (-1); 674 } 675 *ptrptr = cp; 676 return (0); 677} 678 | 697 } 698 cp += l; 699 continue; 700 case NS_CMPRSFLGS: /*%< indirection */ 701 cp++; 702 break; 703 default: /*%< illegal type */ 704 errno = EMSGSIZE; --- 4 unchanged lines hidden (view full) --- 709 if (cp > eom) { 710 errno = EMSGSIZE; 711 return (-1); 712 } 713 *ptrptr = cp; 714 return (0); 715} 716 |
717/* Find the number of octets an nname takes up, including the root label. 718 * (This is basically ns_name_skip() without compression-pointer support.) 719 * ((NOTE: can only return zero if passed-in namesiz argument is zero.)) 720 */ 721ssize_t 722ns_name_length(ns_nname_ct nname, size_t namesiz) { 723 ns_nname_ct orig = nname; 724 u_int n; 725 726 while (namesiz-- > 0 && (n = *nname++) != 0) { 727 if ((n & NS_CMPRSFLGS) != 0) { 728 errno = EISDIR; 729 return (-1); 730 } 731 if (n > namesiz) { 732 errno = EMSGSIZE; 733 return (-1); 734 } 735 nname += n; 736 namesiz -= n; 737 } 738 return (nname - orig); 739} 740 741/* Compare two nname's for equality. Return -1 on error (setting errno). 742 */ 743int 744ns_name_eq(ns_nname_ct a, size_t as, ns_nname_ct b, size_t bs) { 745 ns_nname_ct ae = a + as, be = b + bs; 746 int ac, bc; 747 748 while (ac = *a, bc = *b, ac != 0 && bc != 0) { 749 if ((ac & NS_CMPRSFLGS) != 0 || (bc & NS_CMPRSFLGS) != 0) { 750 errno = EISDIR; 751 return (-1); 752 } 753 if (a + ac >= ae || b + bc >= be) { 754 errno = EMSGSIZE; 755 return (-1); 756 } 757 if (ac != bc || strncasecmp((const char *) ++a, 758 (const char *) ++b, ac) != 0) 759 return (0); 760 a += ac, b += bc; 761 } 762 return (ac == 0 && bc == 0); 763} 764 765/* Is domain "A" owned by (at or below) domain "B"? 766 */ 767int 768ns_name_owned(ns_namemap_ct a, int an, ns_namemap_ct b, int bn) { 769 /* If A is shorter, it cannot be owned by B. */ 770 if (an < bn) 771 return (0); 772 773 /* If they are unequal before the length of the shorter, A cannot... */ 774 while (bn > 0) { 775 if (a->len != b->len || 776 strncasecmp((const char *) a->base, 777 (const char *) b->base, a->len) != 0) 778 return (0); 779 a++, an--; 780 b++, bn--; 781 } 782 783 /* A might be longer or not, but either way, B owns it. */ 784 return (1); 785} 786 787/* Build an array of <base,len> tuples from an nname, top-down order. 788 * Return the number of tuples (labels) thus discovered. 789 */ 790int 791ns_name_map(ns_nname_ct nname, size_t namelen, ns_namemap_t map, int mapsize) { 792 u_int n; 793 int l; 794 795 n = *nname++; 796 namelen--; 797 798 /* Root zone? */ 799 if (n == 0) { 800 /* Extra data follows name? */ 801 if (namelen > 0) { 802 errno = EMSGSIZE; 803 return (-1); 804 } 805 return (0); 806 } 807 808 /* Compression pointer? */ 809 if ((n & NS_CMPRSFLGS) != 0) { 810 errno = EISDIR; 811 return (-1); 812 } 813 814 /* Label too long? */ 815 if (n > namelen) { 816 errno = EMSGSIZE; 817 return (-1); 818 } 819 820 /* Recurse to get rest of name done first. */ 821 l = ns_name_map(nname + n, namelen - n, map, mapsize); 822 if (l < 0) 823 return (-1); 824 825 /* Too many labels? */ 826 if (l >= mapsize) { 827 errno = ENAMETOOLONG; 828 return (-1); 829 } 830 831 /* We're on our way back up-stack, store current map data. */ 832 map[l].base = nname; 833 map[l].len = n; 834 return (l + 1); 835} 836 837/* Count the labels in a domain name. Root counts, so COM. has two. This 838 * is to make the result comparable to the result of ns_name_map(). 839 */ 840int 841ns_name_labels(ns_nname_ct nname, size_t namesiz) { 842 int ret = 0; 843 u_int n; 844 845 while (namesiz-- > 0 && (n = *nname++) != 0) { 846 if ((n & NS_CMPRSFLGS) != 0) { 847 errno = EISDIR; 848 return (-1); 849 } 850 if (n > namesiz) { 851 errno = EMSGSIZE; 852 return (-1); 853 } 854 nname += n; 855 namesiz -= n; 856 ret++; 857 } 858 return (ret + 1); 859} 860 |
|
679/* Private. */ 680 681/*% 682 * Thinking in noninternationalized USASCII (per the DNS spec), 683 * is this characted special ("in need of quoting") ? 684 * 685 * return: 686 *\li boolean. --- 114 unchanged lines hidden (view full) --- 801 char *beg = dn, tc; 802 int b, blen, plen, i; 803 804 if ((blen = (*cp & 0xff)) == 0) 805 blen = 256; 806 plen = (blen + 3) / 4; 807 plen += sizeof("\\[x/]") + (blen > 99 ? 3 : (blen > 9) ? 2 : 1); 808 if (dn + plen >= eom) | 861/* Private. */ 862 863/*% 864 * Thinking in noninternationalized USASCII (per the DNS spec), 865 * is this characted special ("in need of quoting") ? 866 * 867 * return: 868 *\li boolean. --- 114 unchanged lines hidden (view full) --- 983 char *beg = dn, tc; 984 int b, blen, plen, i; 985 986 if ((blen = (*cp & 0xff)) == 0) 987 blen = 256; 988 plen = (blen + 3) / 4; 989 plen += sizeof("\\[x/]") + (blen > 99 ? 3 : (blen > 9) ? 2 : 1); 990 if (dn + plen >= eom) |
809 return(-1); | 991 return (-1); |
810 811 cp++; 812 i = SPRINTF((dn, "\\[x")); 813 if (i < 0) 814 return (-1); 815 dn += i; 816 for (b = blen; b > 7; b -= 8, cp++) { 817 i = SPRINTF((dn, "%02x", *cp & 0xff)); --- 16 unchanged lines hidden (view full) --- 834 dn += i; 835 } 836 i = SPRINTF((dn, "/%d]", blen)); 837 if (i < 0) 838 return (-1); 839 dn += i; 840 841 *cpp = cp; | 992 993 cp++; 994 i = SPRINTF((dn, "\\[x")); 995 if (i < 0) 996 return (-1); 997 dn += i; 998 for (b = blen; b > 7; b -= 8, cp++) { 999 i = SPRINTF((dn, "%02x", *cp & 0xff)); --- 16 unchanged lines hidden (view full) --- 1016 dn += i; 1017 } 1018 i = SPRINTF((dn, "/%d]", blen)); 1019 if (i < 0) 1020 return (-1); 1021 dn += i; 1022 1023 *cpp = cp; |
842 return(dn - beg); | 1024 return (dn - beg); |
843} 844 845static int 846encode_bitsring(const char **bp, const char *end, unsigned char **labelp, | 1025} 1026 1027static int 1028encode_bitsring(const char **bp, const char *end, unsigned char **labelp, |
847 unsigned char ** dst, unsigned const char *eom) | 1029 unsigned char ** dst, unsigned const char *eom) |
848{ 849 int afterslash = 0; 850 const char *cp = *bp; 851 unsigned char *tp; 852 char c; 853 const char *beg_blen; 854 char *end_blen = NULL; 855 int value = 0, count = 0, tbcount = 0, blen = 0; 856 857 beg_blen = end_blen = NULL; 858 859 /* a bitstring must contain at least 2 characters */ 860 if (end - cp < 2) | 1030{ 1031 int afterslash = 0; 1032 const char *cp = *bp; 1033 unsigned char *tp; 1034 char c; 1035 const char *beg_blen; 1036 char *end_blen = NULL; 1037 int value = 0, count = 0, tbcount = 0, blen = 0; 1038 1039 beg_blen = end_blen = NULL; 1040 1041 /* a bitstring must contain at least 2 characters */ 1042 if (end - cp < 2) |
861 return(EINVAL); | 1043 return (EINVAL); |
862 863 /* XXX: currently, only hex strings are supported */ 864 if (*cp++ != 'x') | 1044 1045 /* XXX: currently, only hex strings are supported */ 1046 if (*cp++ != 'x') |
865 return(EINVAL); | 1047 return (EINVAL); |
866 if (!isxdigit((*cp) & 0xff)) /*%< reject '\[x/BLEN]' */ | 1048 if (!isxdigit((*cp) & 0xff)) /*%< reject '\[x/BLEN]' */ |
867 return(EINVAL); | 1049 return (EINVAL); |
868 869 for (tp = *dst + 1; cp < end && tp < eom; cp++) { 870 switch((c = *cp)) { 871 case ']': /*%< end of the bitstring */ 872 if (afterslash) { 873 if (beg_blen == NULL) | 1050 1051 for (tp = *dst + 1; cp < end && tp < eom; cp++) { 1052 switch((c = *cp)) { 1053 case ']': /*%< end of the bitstring */ 1054 if (afterslash) { 1055 if (beg_blen == NULL) |
874 return(EINVAL); | 1056 return (EINVAL); |
875 blen = (int)strtol(beg_blen, &end_blen, 10); 876 if (*end_blen != ']') | 1057 blen = (int)strtol(beg_blen, &end_blen, 10); 1058 if (*end_blen != ']') |
877 return(EINVAL); | 1059 return (EINVAL); |
878 } 879 if (count) 880 *tp++ = ((value << 4) & 0xff); 881 cp++; /*%< skip ']' */ 882 goto done; 883 case '/': 884 afterslash = 1; 885 break; 886 default: 887 if (afterslash) { 888 if (!isdigit(c&0xff)) | 1060 } 1061 if (count) 1062 *tp++ = ((value << 4) & 0xff); 1063 cp++; /*%< skip ']' */ 1064 goto done; 1065 case '/': 1066 afterslash = 1; 1067 break; 1068 default: 1069 if (afterslash) { 1070 if (!isdigit(c&0xff)) |
889 return(EINVAL); | 1071 return (EINVAL); |
890 if (beg_blen == NULL) { 891 892 if (c == '0') { 893 /* blen never begings with 0 */ | 1072 if (beg_blen == NULL) { 1073 1074 if (c == '0') { 1075 /* blen never begings with 0 */ |
894 return(EINVAL); | 1076 return (EINVAL); |
895 } 896 beg_blen = cp; 897 } 898 } else { 899 if (!isxdigit(c&0xff)) | 1077 } 1078 beg_blen = cp; 1079 } 1080 } else { 1081 if (!isxdigit(c&0xff)) |
900 return(EINVAL); | 1082 return (EINVAL); |
901 value <<= 4; 902 value += digitvalue[(int)c]; 903 count += 4; 904 tbcount += 4; 905 if (tbcount > 256) | 1083 value <<= 4; 1084 value += digitvalue[(int)c]; 1085 count += 4; 1086 tbcount += 4; 1087 if (tbcount > 256) |
906 return(EINVAL); | 1088 return (EINVAL); |
907 if (count == 8) { 908 *tp++ = value; 909 count = 0; 910 } 911 } 912 break; 913 } 914 } 915 done: 916 if (cp >= end || tp >= eom) | 1089 if (count == 8) { 1090 *tp++ = value; 1091 count = 0; 1092 } 1093 } 1094 break; 1095 } 1096 } 1097 done: 1098 if (cp >= end || tp >= eom) |
917 return(EMSGSIZE); | 1099 return (EMSGSIZE); |
918 919 /* 920 * bit length validation: 921 * If a <length> is present, the number of digits in the <bit-data> 922 * MUST be just sufficient to contain the number of bits specified 923 * by the <length>. If there are insignificant bits in a final 924 * hexadecimal or octal digit, they MUST be zero. 925 * RFC2673, Section 3.2. 926 */ 927 if (blen > 0) { 928 int traillen; 929 930 if (((blen + 3) & ~3) != tbcount) | 1100 1101 /* 1102 * bit length validation: 1103 * If a <length> is present, the number of digits in the <bit-data> 1104 * MUST be just sufficient to contain the number of bits specified 1105 * by the <length>. If there are insignificant bits in a final 1106 * hexadecimal or octal digit, they MUST be zero. 1107 * RFC2673, Section 3.2. 1108 */ 1109 if (blen > 0) { 1110 int traillen; 1111 1112 if (((blen + 3) & ~3) != tbcount) |
931 return(EINVAL); | 1113 return (EINVAL); |
932 traillen = tbcount - blen; /*%< between 0 and 3 */ 933 if (((value << (8 - traillen)) & 0xff) != 0) | 1114 traillen = tbcount - blen; /*%< between 0 and 3 */ 1115 if (((value << (8 - traillen)) & 0xff) != 0) |
934 return(EINVAL); | 1116 return (EINVAL); |
935 } 936 else 937 blen = tbcount; 938 if (blen == 256) 939 blen = 0; 940 941 /* encode the type and the significant bit fields */ 942 **labelp = DNS_LABELTYPE_BITSTRING; 943 **dst = blen; 944 945 *bp = cp; 946 *dst = tp; 947 | 1117 } 1118 else 1119 blen = tbcount; 1120 if (blen == 256) 1121 blen = 0; 1122 1123 /* encode the type and the significant bit fields */ 1124 **labelp = DNS_LABELTYPE_BITSTRING; 1125 **dst = blen; 1126 1127 *bp = cp; 1128 *dst = tp; 1129 |
948 return(0); | 1130 return (0); |
949} 950 951static int 952labellen(const u_char *lp) 953{ 954 int bitlen; 955 u_char l = *lp; 956 957 if ((l & NS_CMPRSFLGS) == NS_CMPRSFLGS) { 958 /* should be avoided by the caller */ | 1131} 1132 1133static int 1134labellen(const u_char *lp) 1135{ 1136 int bitlen; 1137 u_char l = *lp; 1138 1139 if ((l & NS_CMPRSFLGS) == NS_CMPRSFLGS) { 1140 /* should be avoided by the caller */ |
959 return(-1); | 1141 return (-1); |
960 } 961 962 if ((l & NS_CMPRSFLGS) == NS_TYPE_ELT) { 963 if (l == DNS_LABELTYPE_BITSTRING) { 964 if ((bitlen = *(lp + 1)) == 0) 965 bitlen = 256; | 1142 } 1143 1144 if ((l & NS_CMPRSFLGS) == NS_TYPE_ELT) { 1145 if (l == DNS_LABELTYPE_BITSTRING) { 1146 if ((bitlen = *(lp + 1)) == 0) 1147 bitlen = 256; |
966 return((bitlen + 7 ) / 8 + 1); | 1148 return ((bitlen + 7 ) / 8 + 1); |
967 } | 1149 } |
968 return(-1); /*%< unknwon ELT */ | 1150 return (-1); /*%< unknwon ELT */ |
969 } | 1151 } |
970 return(l); | 1152 return (l); |
971} 972 973/*! \file */ | 1153} 1154 1155/*! \file */ |