1package dns 2 3import ( 4 "encoding/base64" 5 "net" 6 "strconv" 7 "strings" 8) 9 10type parserFunc struct { 11 // Func defines the function that parses the tokens and returns the RR 12 // or an error. The last string contains any comments in the line as 13 // they returned by the lexer as well. 14 Func func(h RR_Header, c chan lex, origin string, file string) (RR, *ParseError, string) 15 // Signals if the RR ending is of variable length, like TXT or records 16 // that have Hexadecimal or Base64 as their last element in the Rdata. Records 17 // that have a fixed ending or for instance A, AAAA, SOA and etc. 18 Variable bool 19} 20 21// Parse the rdata of each rrtype. 22// All data from the channel c is either zString or zBlank. 23// After the rdata there may come a zBlank and then a zNewline 24// or immediately a zNewline. If this is not the case we flag 25// an *ParseError: garbage after rdata. 26func setRR(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { 27 parserfunc, ok := typeToparserFunc[h.Rrtype] 28 if ok { 29 r, e, cm := parserfunc.Func(h, c, o, f) 30 if parserfunc.Variable { 31 return r, e, cm 32 } 33 if e != nil { 34 return nil, e, "" 35 } 36 e, cm = slurpRemainder(c, f) 37 if e != nil { 38 return nil, e, "" 39 } 40 return r, nil, cm 41 } 42 // RFC3957 RR (Unknown RR handling) 43 return setRFC3597(h, c, o, f) 44} 45 46// A remainder of the rdata with embedded spaces, return the parsed string (sans the spaces) 47// or an error 48func endingToString(c chan lex, errstr, f string) (string, *ParseError, string) { 49 s := "" 50 l := <-c // zString 51 for l.value != zNewline && l.value != zEOF { 52 if l.err { 53 return s, &ParseError{f, errstr, l}, "" 54 } 55 switch l.value { 56 case zString: 57 s += l.token 58 case zBlank: // Ok 59 default: 60 return "", &ParseError{f, errstr, l}, "" 61 } 62 l = <-c 63 } 64 return s, nil, l.comment 65} 66 67// A remainder of the rdata with embedded spaces, split on unquoted whitespace 68// and return the parsed string slice or an error 69func endingToTxtSlice(c chan lex, errstr, f string) ([]string, *ParseError, string) { 70 // Get the remaining data until we see a zNewline 71 l := <-c 72 if l.err { 73 return nil, &ParseError{f, errstr, l}, "" 74 } 75 76 // Build the slice 77 s := make([]string, 0) 78 quote := false 79 empty := false 80 for l.value != zNewline && l.value != zEOF { 81 if l.err { 82 return nil, &ParseError{f, errstr, l}, "" 83 } 84 switch l.value { 85 case zString: 86 empty = false 87 if len(l.token) > 255 { 88 // split up tokens that are larger than 255 into 255-chunks 89 sx := []string{} 90 p, i := 0, 255 91 for { 92 if i <= len(l.token) { 93 sx = append(sx, l.token[p:i]) 94 } else { 95 sx = append(sx, l.token[p:]) 96 break 97 98 } 99 p, i = p+255, i+255 100 } 101 s = append(s, sx...) 102 break 103 } 104 105 s = append(s, l.token) 106 case zBlank: 107 if quote { 108 // zBlank can only be seen in between txt parts. 109 return nil, &ParseError{f, errstr, l}, "" 110 } 111 case zQuote: 112 if empty && quote { 113 s = append(s, "") 114 } 115 quote = !quote 116 empty = true 117 default: 118 return nil, &ParseError{f, errstr, l}, "" 119 } 120 l = <-c 121 } 122 if quote { 123 return nil, &ParseError{f, errstr, l}, "" 124 } 125 return s, nil, l.comment 126} 127 128func setA(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { 129 rr := new(A) 130 rr.Hdr = h 131 132 l := <-c 133 if l.length == 0 { // dynamic update rr. 134 return rr, nil, "" 135 } 136 137 rr.A = net.ParseIP(l.token) 138 if rr.A == nil || l.err { 139 return nil, &ParseError{f, "bad A A", l}, "" 140 } 141 return rr, nil, "" 142} 143 144func setAAAA(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { 145 rr := new(AAAA) 146 rr.Hdr = h 147 148 l := <-c 149 if l.length == 0 { // dynamic update rr. 150 return rr, nil, "" 151 } 152 153 rr.AAAA = net.ParseIP(l.token) 154 if rr.AAAA == nil || l.err { 155 return nil, &ParseError{f, "bad AAAA AAAA", l}, "" 156 } 157 return rr, nil, "" 158} 159 160func setNS(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { 161 rr := new(NS) 162 rr.Hdr = h 163 164 l := <-c 165 rr.Ns = l.token 166 if l.length == 0 { // dynamic update rr. 167 return rr, nil, "" 168 } 169 170 name, nameOk := toAbsoluteName(l.token, o) 171 if l.err || !nameOk { 172 return nil, &ParseError{f, "bad NS Ns", l}, "" 173 } 174 rr.Ns = name 175 return rr, nil, "" 176} 177 178func setPTR(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { 179 rr := new(PTR) 180 rr.Hdr = h 181 182 l := <-c 183 rr.Ptr = l.token 184 if l.length == 0 { // dynamic update rr. 185 return rr, nil, "" 186 } 187 188 name, nameOk := toAbsoluteName(l.token, o) 189 if l.err || !nameOk { 190 return nil, &ParseError{f, "bad PTR Ptr", l}, "" 191 } 192 rr.Ptr = name 193 return rr, nil, "" 194} 195 196func setNSAPPTR(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { 197 rr := new(NSAPPTR) 198 rr.Hdr = h 199 200 l := <-c 201 rr.Ptr = l.token 202 if l.length == 0 { // dynamic update rr. 203 return rr, nil, "" 204 } 205 206 name, nameOk := toAbsoluteName(l.token, o) 207 if l.err || !nameOk { 208 return nil, &ParseError{f, "bad NSAP-PTR Ptr", l}, "" 209 } 210 rr.Ptr = name 211 return rr, nil, "" 212} 213 214func setRP(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { 215 rr := new(RP) 216 rr.Hdr = h 217 218 l := <-c 219 rr.Mbox = l.token 220 if l.length == 0 { // dynamic update rr. 221 return rr, nil, "" 222 } 223 224 mbox, mboxOk := toAbsoluteName(l.token, o) 225 if l.err || !mboxOk { 226 return nil, &ParseError{f, "bad RP Mbox", l}, "" 227 } 228 rr.Mbox = mbox 229 230 <-c // zBlank 231 l = <-c 232 rr.Txt = l.token 233 234 txt, txtOk := toAbsoluteName(l.token, o) 235 if l.err || !txtOk { 236 return nil, &ParseError{f, "bad RP Txt", l}, "" 237 } 238 rr.Txt = txt 239 240 return rr, nil, "" 241} 242 243func setMR(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { 244 rr := new(MR) 245 rr.Hdr = h 246 247 l := <-c 248 rr.Mr = l.token 249 if l.length == 0 { // dynamic update rr. 250 return rr, nil, "" 251 } 252 253 name, nameOk := toAbsoluteName(l.token, o) 254 if l.err || !nameOk { 255 return nil, &ParseError{f, "bad MR Mr", l}, "" 256 } 257 rr.Mr = name 258 return rr, nil, "" 259} 260 261func setMB(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { 262 rr := new(MB) 263 rr.Hdr = h 264 265 l := <-c 266 rr.Mb = l.token 267 if l.length == 0 { // dynamic update rr. 268 return rr, nil, "" 269 } 270 271 name, nameOk := toAbsoluteName(l.token, o) 272 if l.err || !nameOk { 273 return nil, &ParseError{f, "bad MB Mb", l}, "" 274 } 275 rr.Mb = name 276 return rr, nil, "" 277} 278 279func setMG(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { 280 rr := new(MG) 281 rr.Hdr = h 282 283 l := <-c 284 rr.Mg = l.token 285 if l.length == 0 { // dynamic update rr. 286 return rr, nil, "" 287 } 288 289 name, nameOk := toAbsoluteName(l.token, o) 290 if l.err || !nameOk { 291 return nil, &ParseError{f, "bad MG Mg", l}, "" 292 } 293 rr.Mg = name 294 return rr, nil, "" 295} 296 297func setHINFO(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { 298 rr := new(HINFO) 299 rr.Hdr = h 300 301 chunks, e, c1 := endingToTxtSlice(c, "bad HINFO Fields", f) 302 if e != nil { 303 return nil, e, c1 304 } 305 306 if ln := len(chunks); ln == 0 { 307 return rr, nil, "" 308 } else if ln == 1 { 309 // Can we split it? 310 if out := strings.Fields(chunks[0]); len(out) > 1 { 311 chunks = out 312 } else { 313 chunks = append(chunks, "") 314 } 315 } 316 317 rr.Cpu = chunks[0] 318 rr.Os = strings.Join(chunks[1:], " ") 319 320 return rr, nil, "" 321} 322 323func setMINFO(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { 324 rr := new(MINFO) 325 rr.Hdr = h 326 327 l := <-c 328 rr.Rmail = l.token 329 if l.length == 0 { // dynamic update rr. 330 return rr, nil, "" 331 } 332 333 rmail, rmailOk := toAbsoluteName(l.token, o) 334 if l.err || !rmailOk { 335 return nil, &ParseError{f, "bad MINFO Rmail", l}, "" 336 } 337 rr.Rmail = rmail 338 339 <-c // zBlank 340 l = <-c 341 rr.Email = l.token 342 343 email, emailOk := toAbsoluteName(l.token, o) 344 if l.err || !emailOk { 345 return nil, &ParseError{f, "bad MINFO Email", l}, "" 346 } 347 rr.Email = email 348 349 return rr, nil, "" 350} 351 352func setMF(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { 353 rr := new(MF) 354 rr.Hdr = h 355 356 l := <-c 357 rr.Mf = l.token 358 if l.length == 0 { // dynamic update rr. 359 return rr, nil, "" 360 } 361 362 name, nameOk := toAbsoluteName(l.token, o) 363 if l.err || !nameOk { 364 return nil, &ParseError{f, "bad MF Mf", l}, "" 365 } 366 rr.Mf = name 367 return rr, nil, "" 368} 369 370func setMD(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { 371 rr := new(MD) 372 rr.Hdr = h 373 374 l := <-c 375 rr.Md = l.token 376 if l.length == 0 { // dynamic update rr. 377 return rr, nil, "" 378 } 379 380 name, nameOk := toAbsoluteName(l.token, o) 381 if l.err || !nameOk { 382 return nil, &ParseError{f, "bad MD Md", l}, "" 383 } 384 rr.Md = name 385 return rr, nil, "" 386} 387 388func setMX(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { 389 rr := new(MX) 390 rr.Hdr = h 391 392 l := <-c 393 if l.length == 0 { // dynamic update rr. 394 return rr, nil, "" 395 } 396 397 i, e := strconv.ParseUint(l.token, 10, 16) 398 if e != nil || l.err { 399 return nil, &ParseError{f, "bad MX Pref", l}, "" 400 } 401 rr.Preference = uint16(i) 402 403 <-c // zBlank 404 l = <-c // zString 405 rr.Mx = l.token 406 407 name, nameOk := toAbsoluteName(l.token, o) 408 if l.err || !nameOk { 409 return nil, &ParseError{f, "bad MX Mx", l}, "" 410 } 411 rr.Mx = name 412 413 return rr, nil, "" 414} 415 416func setRT(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { 417 rr := new(RT) 418 rr.Hdr = h 419 420 l := <-c 421 if l.length == 0 { // dynamic update rr. 422 return rr, nil, "" 423 } 424 425 i, e := strconv.ParseUint(l.token, 10, 16) 426 if e != nil { 427 return nil, &ParseError{f, "bad RT Preference", l}, "" 428 } 429 rr.Preference = uint16(i) 430 431 <-c // zBlank 432 l = <-c // zString 433 rr.Host = l.token 434 435 name, nameOk := toAbsoluteName(l.token, o) 436 if l.err || !nameOk { 437 return nil, &ParseError{f, "bad RT Host", l}, "" 438 } 439 rr.Host = name 440 441 return rr, nil, "" 442} 443 444func setAFSDB(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { 445 rr := new(AFSDB) 446 rr.Hdr = h 447 448 l := <-c 449 if l.length == 0 { // dynamic update rr. 450 return rr, nil, "" 451 } 452 453 i, e := strconv.ParseUint(l.token, 10, 16) 454 if e != nil || l.err { 455 return nil, &ParseError{f, "bad AFSDB Subtype", l}, "" 456 } 457 rr.Subtype = uint16(i) 458 459 <-c // zBlank 460 l = <-c // zString 461 rr.Hostname = l.token 462 463 name, nameOk := toAbsoluteName(l.token, o) 464 if l.err || !nameOk { 465 return nil, &ParseError{f, "bad AFSDB Hostname", l}, "" 466 } 467 rr.Hostname = name 468 return rr, nil, "" 469} 470 471func setX25(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { 472 rr := new(X25) 473 rr.Hdr = h 474 475 l := <-c 476 if l.length == 0 { // dynamic update rr. 477 return rr, nil, "" 478 } 479 480 if l.err { 481 return nil, &ParseError{f, "bad X25 PSDNAddress", l}, "" 482 } 483 rr.PSDNAddress = l.token 484 return rr, nil, "" 485} 486 487func setKX(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { 488 rr := new(KX) 489 rr.Hdr = h 490 491 l := <-c 492 if l.length == 0 { // dynamic update rr. 493 return rr, nil, "" 494 } 495 496 i, e := strconv.ParseUint(l.token, 10, 16) 497 if e != nil || l.err { 498 return nil, &ParseError{f, "bad KX Pref", l}, "" 499 } 500 rr.Preference = uint16(i) 501 502 <-c // zBlank 503 l = <-c // zString 504 rr.Exchanger = l.token 505 506 name, nameOk := toAbsoluteName(l.token, o) 507 if l.err || !nameOk { 508 return nil, &ParseError{f, "bad KX Exchanger", l}, "" 509 } 510 rr.Exchanger = name 511 return rr, nil, "" 512} 513 514func setCNAME(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { 515 rr := new(CNAME) 516 rr.Hdr = h 517 518 l := <-c 519 rr.Target = l.token 520 if l.length == 0 { // dynamic update rr. 521 return rr, nil, "" 522 } 523 524 name, nameOk := toAbsoluteName(l.token, o) 525 if l.err || !nameOk { 526 return nil, &ParseError{f, "bad CNAME Target", l}, "" 527 } 528 rr.Target = name 529 return rr, nil, "" 530} 531 532func setDNAME(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { 533 rr := new(DNAME) 534 rr.Hdr = h 535 536 l := <-c 537 rr.Target = l.token 538 if l.length == 0 { // dynamic update rr. 539 return rr, nil, "" 540 } 541 542 name, nameOk := toAbsoluteName(l.token, o) 543 if l.err || !nameOk { 544 return nil, &ParseError{f, "bad DNAME Target", l}, "" 545 } 546 rr.Target = name 547 return rr, nil, "" 548} 549 550func setSOA(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { 551 rr := new(SOA) 552 rr.Hdr = h 553 554 l := <-c 555 rr.Ns = l.token 556 if l.length == 0 { // dynamic update rr. 557 return rr, nil, "" 558 } 559 560 ns, nsOk := toAbsoluteName(l.token, o) 561 if l.err || !nsOk { 562 return nil, &ParseError{f, "bad SOA Ns", l}, "" 563 } 564 rr.Ns = ns 565 566 <-c // zBlank 567 l = <-c 568 rr.Mbox = l.token 569 570 mbox, mboxOk := toAbsoluteName(l.token, o) 571 if l.err || !mboxOk { 572 return nil, &ParseError{f, "bad SOA Mbox", l}, "" 573 } 574 rr.Mbox = mbox 575 576 <-c // zBlank 577 578 var ( 579 v uint32 580 ok bool 581 ) 582 for i := 0; i < 5; i++ { 583 l = <-c 584 if l.err { 585 return nil, &ParseError{f, "bad SOA zone parameter", l}, "" 586 } 587 if j, e := strconv.ParseUint(l.token, 10, 32); e != nil { 588 if i == 0 { 589 // Serial must be a number 590 return nil, &ParseError{f, "bad SOA zone parameter", l}, "" 591 } 592 // We allow other fields to be unitful duration strings 593 if v, ok = stringToTTL(l.token); !ok { 594 return nil, &ParseError{f, "bad SOA zone parameter", l}, "" 595 596 } 597 } else { 598 v = uint32(j) 599 } 600 switch i { 601 case 0: 602 rr.Serial = v 603 <-c // zBlank 604 case 1: 605 rr.Refresh = v 606 <-c // zBlank 607 case 2: 608 rr.Retry = v 609 <-c // zBlank 610 case 3: 611 rr.Expire = v 612 <-c // zBlank 613 case 4: 614 rr.Minttl = v 615 } 616 } 617 return rr, nil, "" 618} 619 620func setSRV(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { 621 rr := new(SRV) 622 rr.Hdr = h 623 624 l := <-c 625 if l.length == 0 { // dynamic update rr. 626 return rr, nil, "" 627 } 628 629 i, e := strconv.ParseUint(l.token, 10, 16) 630 if e != nil || l.err { 631 return nil, &ParseError{f, "bad SRV Priority", l}, "" 632 } 633 rr.Priority = uint16(i) 634 635 <-c // zBlank 636 l = <-c // zString 637 i, e = strconv.ParseUint(l.token, 10, 16) 638 if e != nil || l.err { 639 return nil, &ParseError{f, "bad SRV Weight", l}, "" 640 } 641 rr.Weight = uint16(i) 642 643 <-c // zBlank 644 l = <-c // zString 645 i, e = strconv.ParseUint(l.token, 10, 16) 646 if e != nil || l.err { 647 return nil, &ParseError{f, "bad SRV Port", l}, "" 648 } 649 rr.Port = uint16(i) 650 651 <-c // zBlank 652 l = <-c // zString 653 rr.Target = l.token 654 655 name, nameOk := toAbsoluteName(l.token, o) 656 if l.err || !nameOk { 657 return nil, &ParseError{f, "bad SRV Target", l}, "" 658 } 659 rr.Target = name 660 return rr, nil, "" 661} 662 663func setNAPTR(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { 664 rr := new(NAPTR) 665 rr.Hdr = h 666 667 l := <-c 668 if l.length == 0 { // dynamic update rr. 669 return rr, nil, "" 670 } 671 672 i, e := strconv.ParseUint(l.token, 10, 16) 673 if e != nil || l.err { 674 return nil, &ParseError{f, "bad NAPTR Order", l}, "" 675 } 676 rr.Order = uint16(i) 677 678 <-c // zBlank 679 l = <-c // zString 680 i, e = strconv.ParseUint(l.token, 10, 16) 681 if e != nil || l.err { 682 return nil, &ParseError{f, "bad NAPTR Preference", l}, "" 683 } 684 rr.Preference = uint16(i) 685 686 // Flags 687 <-c // zBlank 688 l = <-c // _QUOTE 689 if l.value != zQuote { 690 return nil, &ParseError{f, "bad NAPTR Flags", l}, "" 691 } 692 l = <-c // Either String or Quote 693 if l.value == zString { 694 rr.Flags = l.token 695 l = <-c // _QUOTE 696 if l.value != zQuote { 697 return nil, &ParseError{f, "bad NAPTR Flags", l}, "" 698 } 699 } else if l.value == zQuote { 700 rr.Flags = "" 701 } else { 702 return nil, &ParseError{f, "bad NAPTR Flags", l}, "" 703 } 704 705 // Service 706 <-c // zBlank 707 l = <-c // _QUOTE 708 if l.value != zQuote { 709 return nil, &ParseError{f, "bad NAPTR Service", l}, "" 710 } 711 l = <-c // Either String or Quote 712 if l.value == zString { 713 rr.Service = l.token 714 l = <-c // _QUOTE 715 if l.value != zQuote { 716 return nil, &ParseError{f, "bad NAPTR Service", l}, "" 717 } 718 } else if l.value == zQuote { 719 rr.Service = "" 720 } else { 721 return nil, &ParseError{f, "bad NAPTR Service", l}, "" 722 } 723 724 // Regexp 725 <-c // zBlank 726 l = <-c // _QUOTE 727 if l.value != zQuote { 728 return nil, &ParseError{f, "bad NAPTR Regexp", l}, "" 729 } 730 l = <-c // Either String or Quote 731 if l.value == zString { 732 rr.Regexp = l.token 733 l = <-c // _QUOTE 734 if l.value != zQuote { 735 return nil, &ParseError{f, "bad NAPTR Regexp", l}, "" 736 } 737 } else if l.value == zQuote { 738 rr.Regexp = "" 739 } else { 740 return nil, &ParseError{f, "bad NAPTR Regexp", l}, "" 741 } 742 743 // After quote no space?? 744 <-c // zBlank 745 l = <-c // zString 746 rr.Replacement = l.token 747 748 name, nameOk := toAbsoluteName(l.token, o) 749 if l.err || !nameOk { 750 return nil, &ParseError{f, "bad NAPTR Replacement", l}, "" 751 } 752 rr.Replacement = name 753 return rr, nil, "" 754} 755 756func setTALINK(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { 757 rr := new(TALINK) 758 rr.Hdr = h 759 760 l := <-c 761 rr.PreviousName = l.token 762 if l.length == 0 { // dynamic update rr. 763 return rr, nil, "" 764 } 765 766 previousName, previousNameOk := toAbsoluteName(l.token, o) 767 if l.err || !previousNameOk { 768 return nil, &ParseError{f, "bad TALINK PreviousName", l}, "" 769 } 770 rr.PreviousName = previousName 771 772 <-c // zBlank 773 l = <-c 774 rr.NextName = l.token 775 776 nextName, nextNameOk := toAbsoluteName(l.token, o) 777 if l.err || !nextNameOk { 778 return nil, &ParseError{f, "bad TALINK NextName", l}, "" 779 } 780 rr.NextName = nextName 781 782 return rr, nil, "" 783} 784 785func setLOC(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { 786 rr := new(LOC) 787 rr.Hdr = h 788 // Non zero defaults for LOC record, see RFC 1876, Section 3. 789 rr.HorizPre = 165 // 10000 790 rr.VertPre = 162 // 10 791 rr.Size = 18 // 1 792 ok := false 793 794 // North 795 l := <-c 796 if l.length == 0 { // dynamic update rr. 797 return rr, nil, "" 798 } 799 i, e := strconv.ParseUint(l.token, 10, 32) 800 if e != nil || l.err { 801 return nil, &ParseError{f, "bad LOC Latitude", l}, "" 802 } 803 rr.Latitude = 1000 * 60 * 60 * uint32(i) 804 805 <-c // zBlank 806 // Either number, 'N' or 'S' 807 l = <-c 808 if rr.Latitude, ok = locCheckNorth(l.token, rr.Latitude); ok { 809 goto East 810 } 811 i, e = strconv.ParseUint(l.token, 10, 32) 812 if e != nil || l.err { 813 return nil, &ParseError{f, "bad LOC Latitude minutes", l}, "" 814 } 815 rr.Latitude += 1000 * 60 * uint32(i) 816 817 <-c // zBlank 818 l = <-c 819 if i, e := strconv.ParseFloat(l.token, 32); e != nil || l.err { 820 return nil, &ParseError{f, "bad LOC Latitude seconds", l}, "" 821 } else { 822 rr.Latitude += uint32(1000 * i) 823 } 824 <-c // zBlank 825 // Either number, 'N' or 'S' 826 l = <-c 827 if rr.Latitude, ok = locCheckNorth(l.token, rr.Latitude); ok { 828 goto East 829 } 830 // If still alive, flag an error 831 return nil, &ParseError{f, "bad LOC Latitude North/South", l}, "" 832 833East: 834 // East 835 <-c // zBlank 836 l = <-c 837 if i, e := strconv.ParseUint(l.token, 10, 32); e != nil || l.err { 838 return nil, &ParseError{f, "bad LOC Longitude", l}, "" 839 } else { 840 rr.Longitude = 1000 * 60 * 60 * uint32(i) 841 } 842 <-c // zBlank 843 // Either number, 'E' or 'W' 844 l = <-c 845 if rr.Longitude, ok = locCheckEast(l.token, rr.Longitude); ok { 846 goto Altitude 847 } 848 if i, e := strconv.ParseUint(l.token, 10, 32); e != nil || l.err { 849 return nil, &ParseError{f, "bad LOC Longitude minutes", l}, "" 850 } else { 851 rr.Longitude += 1000 * 60 * uint32(i) 852 } 853 <-c // zBlank 854 l = <-c 855 if i, e := strconv.ParseFloat(l.token, 32); e != nil || l.err { 856 return nil, &ParseError{f, "bad LOC Longitude seconds", l}, "" 857 } else { 858 rr.Longitude += uint32(1000 * i) 859 } 860 <-c // zBlank 861 // Either number, 'E' or 'W' 862 l = <-c 863 if rr.Longitude, ok = locCheckEast(l.token, rr.Longitude); ok { 864 goto Altitude 865 } 866 // If still alive, flag an error 867 return nil, &ParseError{f, "bad LOC Longitude East/West", l}, "" 868 869Altitude: 870 <-c // zBlank 871 l = <-c 872 if l.length == 0 || l.err { 873 return nil, &ParseError{f, "bad LOC Altitude", l}, "" 874 } 875 if l.token[len(l.token)-1] == 'M' || l.token[len(l.token)-1] == 'm' { 876 l.token = l.token[0 : len(l.token)-1] 877 } 878 if i, e := strconv.ParseFloat(l.token, 32); e != nil { 879 return nil, &ParseError{f, "bad LOC Altitude", l}, "" 880 } else { 881 rr.Altitude = uint32(i*100.0 + 10000000.0 + 0.5) 882 } 883 884 // And now optionally the other values 885 l = <-c 886 count := 0 887 for l.value != zNewline && l.value != zEOF { 888 switch l.value { 889 case zString: 890 switch count { 891 case 0: // Size 892 e, m, ok := stringToCm(l.token) 893 if !ok { 894 return nil, &ParseError{f, "bad LOC Size", l}, "" 895 } 896 rr.Size = (e & 0x0f) | (m << 4 & 0xf0) 897 case 1: // HorizPre 898 e, m, ok := stringToCm(l.token) 899 if !ok { 900 return nil, &ParseError{f, "bad LOC HorizPre", l}, "" 901 } 902 rr.HorizPre = (e & 0x0f) | (m << 4 & 0xf0) 903 case 2: // VertPre 904 e, m, ok := stringToCm(l.token) 905 if !ok { 906 return nil, &ParseError{f, "bad LOC VertPre", l}, "" 907 } 908 rr.VertPre = (e & 0x0f) | (m << 4 & 0xf0) 909 } 910 count++ 911 case zBlank: 912 // Ok 913 default: 914 return nil, &ParseError{f, "bad LOC Size, HorizPre or VertPre", l}, "" 915 } 916 l = <-c 917 } 918 return rr, nil, "" 919} 920 921func setHIP(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { 922 rr := new(HIP) 923 rr.Hdr = h 924 925 // HitLength is not represented 926 l := <-c 927 if l.length == 0 { // dynamic update rr. 928 return rr, nil, l.comment 929 } 930 931 i, e := strconv.ParseUint(l.token, 10, 8) 932 if e != nil || l.err { 933 return nil, &ParseError{f, "bad HIP PublicKeyAlgorithm", l}, "" 934 } 935 rr.PublicKeyAlgorithm = uint8(i) 936 937 <-c // zBlank 938 l = <-c // zString 939 if l.length == 0 || l.err { 940 return nil, &ParseError{f, "bad HIP Hit", l}, "" 941 } 942 rr.Hit = l.token // This can not contain spaces, see RFC 5205 Section 6. 943 rr.HitLength = uint8(len(rr.Hit)) / 2 944 945 <-c // zBlank 946 l = <-c // zString 947 if l.length == 0 || l.err { 948 return nil, &ParseError{f, "bad HIP PublicKey", l}, "" 949 } 950 rr.PublicKey = l.token // This cannot contain spaces 951 rr.PublicKeyLength = uint16(base64.StdEncoding.DecodedLen(len(rr.PublicKey))) 952 953 // RendezvousServers (if any) 954 l = <-c 955 var xs []string 956 for l.value != zNewline && l.value != zEOF { 957 switch l.value { 958 case zString: 959 name, nameOk := toAbsoluteName(l.token, o) 960 if l.err || !nameOk { 961 return nil, &ParseError{f, "bad HIP RendezvousServers", l}, "" 962 } 963 xs = append(xs, name) 964 case zBlank: 965 // Ok 966 default: 967 return nil, &ParseError{f, "bad HIP RendezvousServers", l}, "" 968 } 969 l = <-c 970 } 971 rr.RendezvousServers = xs 972 return rr, nil, l.comment 973} 974 975func setCERT(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { 976 rr := new(CERT) 977 rr.Hdr = h 978 979 l := <-c 980 if l.length == 0 { // dynamic update rr. 981 return rr, nil, l.comment 982 } 983 984 if v, ok := StringToCertType[l.token]; ok { 985 rr.Type = v 986 } else if i, e := strconv.ParseUint(l.token, 10, 16); e != nil { 987 return nil, &ParseError{f, "bad CERT Type", l}, "" 988 } else { 989 rr.Type = uint16(i) 990 } 991 <-c // zBlank 992 l = <-c // zString 993 i, e := strconv.ParseUint(l.token, 10, 16) 994 if e != nil || l.err { 995 return nil, &ParseError{f, "bad CERT KeyTag", l}, "" 996 } 997 rr.KeyTag = uint16(i) 998 <-c // zBlank 999 l = <-c // zString 1000 if v, ok := StringToAlgorithm[l.token]; ok { 1001 rr.Algorithm = v 1002 } else if i, e := strconv.ParseUint(l.token, 10, 8); e != nil { 1003 return nil, &ParseError{f, "bad CERT Algorithm", l}, "" 1004 } else { 1005 rr.Algorithm = uint8(i) 1006 } 1007 s, e1, c1 := endingToString(c, "bad CERT Certificate", f) 1008 if e1 != nil { 1009 return nil, e1, c1 1010 } 1011 rr.Certificate = s 1012 return rr, nil, c1 1013} 1014 1015func setOPENPGPKEY(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { 1016 rr := new(OPENPGPKEY) 1017 rr.Hdr = h 1018 1019 s, e, c1 := endingToString(c, "bad OPENPGPKEY PublicKey", f) 1020 if e != nil { 1021 return nil, e, c1 1022 } 1023 rr.PublicKey = s 1024 return rr, nil, c1 1025} 1026 1027func setCSYNC(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { 1028 rr := new(CSYNC) 1029 rr.Hdr = h 1030 1031 l := <-c 1032 if l.length == 0 { // dynamic update rr. 1033 return rr, nil, l.comment 1034 } 1035 j, e := strconv.ParseUint(l.token, 10, 32) 1036 if e != nil { 1037 // Serial must be a number 1038 return nil, &ParseError{f, "bad CSYNC serial", l}, "" 1039 } 1040 rr.Serial = uint32(j) 1041 1042 <-c // zBlank 1043 1044 l = <-c 1045 j, e = strconv.ParseUint(l.token, 10, 16) 1046 if e != nil { 1047 // Serial must be a number 1048 return nil, &ParseError{f, "bad CSYNC flags", l}, "" 1049 } 1050 rr.Flags = uint16(j) 1051 1052 rr.TypeBitMap = make([]uint16, 0) 1053 var ( 1054 k uint16 1055 ok bool 1056 ) 1057 l = <-c 1058 for l.value != zNewline && l.value != zEOF { 1059 switch l.value { 1060 case zBlank: 1061 // Ok 1062 case zString: 1063 if k, ok = StringToType[l.tokenUpper]; !ok { 1064 if k, ok = typeToInt(l.tokenUpper); !ok { 1065 return nil, &ParseError{f, "bad CSYNC TypeBitMap", l}, "" 1066 } 1067 } 1068 rr.TypeBitMap = append(rr.TypeBitMap, k) 1069 default: 1070 return nil, &ParseError{f, "bad CSYNC TypeBitMap", l}, "" 1071 } 1072 l = <-c 1073 } 1074 return rr, nil, l.comment 1075} 1076 1077func setSIG(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { 1078 r, e, s := setRRSIG(h, c, o, f) 1079 if r != nil { 1080 return &SIG{*r.(*RRSIG)}, e, s 1081 } 1082 return nil, e, s 1083} 1084 1085func setRRSIG(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { 1086 rr := new(RRSIG) 1087 rr.Hdr = h 1088 1089 l := <-c 1090 if l.length == 0 { // dynamic update rr. 1091 return rr, nil, l.comment 1092 } 1093 1094 if t, ok := StringToType[l.tokenUpper]; !ok { 1095 if strings.HasPrefix(l.tokenUpper, "TYPE") { 1096 t, ok = typeToInt(l.tokenUpper) 1097 if !ok { 1098 return nil, &ParseError{f, "bad RRSIG Typecovered", l}, "" 1099 } 1100 rr.TypeCovered = t 1101 } else { 1102 return nil, &ParseError{f, "bad RRSIG Typecovered", l}, "" 1103 } 1104 } else { 1105 rr.TypeCovered = t 1106 } 1107 1108 <-c // zBlank 1109 l = <-c 1110 i, err := strconv.ParseUint(l.token, 10, 8) 1111 if err != nil || l.err { 1112 return nil, &ParseError{f, "bad RRSIG Algorithm", l}, "" 1113 } 1114 rr.Algorithm = uint8(i) 1115 1116 <-c // zBlank 1117 l = <-c 1118 i, err = strconv.ParseUint(l.token, 10, 8) 1119 if err != nil || l.err { 1120 return nil, &ParseError{f, "bad RRSIG Labels", l}, "" 1121 } 1122 rr.Labels = uint8(i) 1123 1124 <-c // zBlank 1125 l = <-c 1126 i, err = strconv.ParseUint(l.token, 10, 32) 1127 if err != nil || l.err { 1128 return nil, &ParseError{f, "bad RRSIG OrigTtl", l}, "" 1129 } 1130 rr.OrigTtl = uint32(i) 1131 1132 <-c // zBlank 1133 l = <-c 1134 if i, err := StringToTime(l.token); err != nil { 1135 // Try to see if all numeric and use it as epoch 1136 if i, err := strconv.ParseInt(l.token, 10, 64); err == nil { 1137 // TODO(miek): error out on > MAX_UINT32, same below 1138 rr.Expiration = uint32(i) 1139 } else { 1140 return nil, &ParseError{f, "bad RRSIG Expiration", l}, "" 1141 } 1142 } else { 1143 rr.Expiration = i 1144 } 1145 1146 <-c // zBlank 1147 l = <-c 1148 if i, err := StringToTime(l.token); err != nil { 1149 if i, err := strconv.ParseInt(l.token, 10, 64); err == nil { 1150 rr.Inception = uint32(i) 1151 } else { 1152 return nil, &ParseError{f, "bad RRSIG Inception", l}, "" 1153 } 1154 } else { 1155 rr.Inception = i 1156 } 1157 1158 <-c // zBlank 1159 l = <-c 1160 i, err = strconv.ParseUint(l.token, 10, 16) 1161 if err != nil || l.err { 1162 return nil, &ParseError{f, "bad RRSIG KeyTag", l}, "" 1163 } 1164 rr.KeyTag = uint16(i) 1165 1166 <-c // zBlank 1167 l = <-c 1168 rr.SignerName = l.token 1169 name, nameOk := toAbsoluteName(l.token, o) 1170 if l.err || !nameOk { 1171 return nil, &ParseError{f, "bad RRSIG SignerName", l}, "" 1172 } 1173 rr.SignerName = name 1174 1175 s, e, c1 := endingToString(c, "bad RRSIG Signature", f) 1176 if e != nil { 1177 return nil, e, c1 1178 } 1179 rr.Signature = s 1180 1181 return rr, nil, c1 1182} 1183 1184func setNSEC(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { 1185 rr := new(NSEC) 1186 rr.Hdr = h 1187 1188 l := <-c 1189 rr.NextDomain = l.token 1190 if l.length == 0 { // dynamic update rr. 1191 return rr, nil, l.comment 1192 } 1193 1194 name, nameOk := toAbsoluteName(l.token, o) 1195 if l.err || !nameOk { 1196 return nil, &ParseError{f, "bad NSEC NextDomain", l}, "" 1197 } 1198 rr.NextDomain = name 1199 1200 rr.TypeBitMap = make([]uint16, 0) 1201 var ( 1202 k uint16 1203 ok bool 1204 ) 1205 l = <-c 1206 for l.value != zNewline && l.value != zEOF { 1207 switch l.value { 1208 case zBlank: 1209 // Ok 1210 case zString: 1211 if k, ok = StringToType[l.tokenUpper]; !ok { 1212 if k, ok = typeToInt(l.tokenUpper); !ok { 1213 return nil, &ParseError{f, "bad NSEC TypeBitMap", l}, "" 1214 } 1215 } 1216 rr.TypeBitMap = append(rr.TypeBitMap, k) 1217 default: 1218 return nil, &ParseError{f, "bad NSEC TypeBitMap", l}, "" 1219 } 1220 l = <-c 1221 } 1222 return rr, nil, l.comment 1223} 1224 1225func setNSEC3(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { 1226 rr := new(NSEC3) 1227 rr.Hdr = h 1228 1229 l := <-c 1230 if l.length == 0 { // dynamic update rr. 1231 return rr, nil, l.comment 1232 } 1233 1234 i, e := strconv.ParseUint(l.token, 10, 8) 1235 if e != nil || l.err { 1236 return nil, &ParseError{f, "bad NSEC3 Hash", l}, "" 1237 } 1238 rr.Hash = uint8(i) 1239 <-c // zBlank 1240 l = <-c 1241 i, e = strconv.ParseUint(l.token, 10, 8) 1242 if e != nil || l.err { 1243 return nil, &ParseError{f, "bad NSEC3 Flags", l}, "" 1244 } 1245 rr.Flags = uint8(i) 1246 <-c // zBlank 1247 l = <-c 1248 i, e = strconv.ParseUint(l.token, 10, 16) 1249 if e != nil || l.err { 1250 return nil, &ParseError{f, "bad NSEC3 Iterations", l}, "" 1251 } 1252 rr.Iterations = uint16(i) 1253 <-c 1254 l = <-c 1255 if len(l.token) == 0 || l.err { 1256 return nil, &ParseError{f, "bad NSEC3 Salt", l}, "" 1257 } 1258 rr.SaltLength = uint8(len(l.token)) / 2 1259 rr.Salt = l.token 1260 1261 <-c 1262 l = <-c 1263 if len(l.token) == 0 || l.err { 1264 return nil, &ParseError{f, "bad NSEC3 NextDomain", l}, "" 1265 } 1266 rr.HashLength = 20 // Fix for NSEC3 (sha1 160 bits) 1267 rr.NextDomain = l.token 1268 1269 rr.TypeBitMap = make([]uint16, 0) 1270 var ( 1271 k uint16 1272 ok bool 1273 ) 1274 l = <-c 1275 for l.value != zNewline && l.value != zEOF { 1276 switch l.value { 1277 case zBlank: 1278 // Ok 1279 case zString: 1280 if k, ok = StringToType[l.tokenUpper]; !ok { 1281 if k, ok = typeToInt(l.tokenUpper); !ok { 1282 return nil, &ParseError{f, "bad NSEC3 TypeBitMap", l}, "" 1283 } 1284 } 1285 rr.TypeBitMap = append(rr.TypeBitMap, k) 1286 default: 1287 return nil, &ParseError{f, "bad NSEC3 TypeBitMap", l}, "" 1288 } 1289 l = <-c 1290 } 1291 return rr, nil, l.comment 1292} 1293 1294func setNSEC3PARAM(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { 1295 rr := new(NSEC3PARAM) 1296 rr.Hdr = h 1297 1298 l := <-c 1299 if l.length == 0 { // dynamic update rr. 1300 return rr, nil, "" 1301 } 1302 1303 i, e := strconv.ParseUint(l.token, 10, 8) 1304 if e != nil || l.err { 1305 return nil, &ParseError{f, "bad NSEC3PARAM Hash", l}, "" 1306 } 1307 rr.Hash = uint8(i) 1308 <-c // zBlank 1309 l = <-c 1310 i, e = strconv.ParseUint(l.token, 10, 8) 1311 if e != nil || l.err { 1312 return nil, &ParseError{f, "bad NSEC3PARAM Flags", l}, "" 1313 } 1314 rr.Flags = uint8(i) 1315 <-c // zBlank 1316 l = <-c 1317 i, e = strconv.ParseUint(l.token, 10, 16) 1318 if e != nil || l.err { 1319 return nil, &ParseError{f, "bad NSEC3PARAM Iterations", l}, "" 1320 } 1321 rr.Iterations = uint16(i) 1322 <-c 1323 l = <-c 1324 rr.SaltLength = uint8(len(l.token)) 1325 rr.Salt = l.token 1326 return rr, nil, "" 1327} 1328 1329func setEUI48(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { 1330 rr := new(EUI48) 1331 rr.Hdr = h 1332 1333 l := <-c 1334 if l.length == 0 { // dynamic update rr. 1335 return rr, nil, "" 1336 } 1337 1338 if l.length != 17 || l.err { 1339 return nil, &ParseError{f, "bad EUI48 Address", l}, "" 1340 } 1341 addr := make([]byte, 12) 1342 dash := 0 1343 for i := 0; i < 10; i += 2 { 1344 addr[i] = l.token[i+dash] 1345 addr[i+1] = l.token[i+1+dash] 1346 dash++ 1347 if l.token[i+1+dash] != '-' { 1348 return nil, &ParseError{f, "bad EUI48 Address", l}, "" 1349 } 1350 } 1351 addr[10] = l.token[15] 1352 addr[11] = l.token[16] 1353 1354 i, e := strconv.ParseUint(string(addr), 16, 48) 1355 if e != nil { 1356 return nil, &ParseError{f, "bad EUI48 Address", l}, "" 1357 } 1358 rr.Address = i 1359 return rr, nil, "" 1360} 1361 1362func setEUI64(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { 1363 rr := new(EUI64) 1364 rr.Hdr = h 1365 1366 l := <-c 1367 if l.length == 0 { // dynamic update rr. 1368 return rr, nil, "" 1369 } 1370 1371 if l.length != 23 || l.err { 1372 return nil, &ParseError{f, "bad EUI64 Address", l}, "" 1373 } 1374 addr := make([]byte, 16) 1375 dash := 0 1376 for i := 0; i < 14; i += 2 { 1377 addr[i] = l.token[i+dash] 1378 addr[i+1] = l.token[i+1+dash] 1379 dash++ 1380 if l.token[i+1+dash] != '-' { 1381 return nil, &ParseError{f, "bad EUI64 Address", l}, "" 1382 } 1383 } 1384 addr[14] = l.token[21] 1385 addr[15] = l.token[22] 1386 1387 i, e := strconv.ParseUint(string(addr), 16, 64) 1388 if e != nil { 1389 return nil, &ParseError{f, "bad EUI68 Address", l}, "" 1390 } 1391 rr.Address = uint64(i) 1392 return rr, nil, "" 1393} 1394 1395func setSSHFP(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { 1396 rr := new(SSHFP) 1397 rr.Hdr = h 1398 1399 l := <-c 1400 if l.length == 0 { // dynamic update rr. 1401 return rr, nil, "" 1402 } 1403 1404 i, e := strconv.ParseUint(l.token, 10, 8) 1405 if e != nil || l.err { 1406 return nil, &ParseError{f, "bad SSHFP Algorithm", l}, "" 1407 } 1408 rr.Algorithm = uint8(i) 1409 <-c // zBlank 1410 l = <-c 1411 i, e = strconv.ParseUint(l.token, 10, 8) 1412 if e != nil || l.err { 1413 return nil, &ParseError{f, "bad SSHFP Type", l}, "" 1414 } 1415 rr.Type = uint8(i) 1416 <-c // zBlank 1417 s, e1, c1 := endingToString(c, "bad SSHFP Fingerprint", f) 1418 if e1 != nil { 1419 return nil, e1, c1 1420 } 1421 rr.FingerPrint = s 1422 return rr, nil, "" 1423} 1424 1425func setDNSKEYs(h RR_Header, c chan lex, o, f, typ string) (RR, *ParseError, string) { 1426 rr := new(DNSKEY) 1427 rr.Hdr = h 1428 1429 l := <-c 1430 if l.length == 0 { // dynamic update rr. 1431 return rr, nil, l.comment 1432 } 1433 1434 i, e := strconv.ParseUint(l.token, 10, 16) 1435 if e != nil || l.err { 1436 return nil, &ParseError{f, "bad " + typ + " Flags", l}, "" 1437 } 1438 rr.Flags = uint16(i) 1439 <-c // zBlank 1440 l = <-c // zString 1441 i, e = strconv.ParseUint(l.token, 10, 8) 1442 if e != nil || l.err { 1443 return nil, &ParseError{f, "bad " + typ + " Protocol", l}, "" 1444 } 1445 rr.Protocol = uint8(i) 1446 <-c // zBlank 1447 l = <-c // zString 1448 i, e = strconv.ParseUint(l.token, 10, 8) 1449 if e != nil || l.err { 1450 return nil, &ParseError{f, "bad " + typ + " Algorithm", l}, "" 1451 } 1452 rr.Algorithm = uint8(i) 1453 s, e1, c1 := endingToString(c, "bad "+typ+" PublicKey", f) 1454 if e1 != nil { 1455 return nil, e1, c1 1456 } 1457 rr.PublicKey = s 1458 return rr, nil, c1 1459} 1460 1461func setKEY(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { 1462 r, e, s := setDNSKEYs(h, c, o, f, "KEY") 1463 if r != nil { 1464 return &KEY{*r.(*DNSKEY)}, e, s 1465 } 1466 return nil, e, s 1467} 1468 1469func setDNSKEY(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { 1470 r, e, s := setDNSKEYs(h, c, o, f, "DNSKEY") 1471 return r, e, s 1472} 1473 1474func setCDNSKEY(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { 1475 r, e, s := setDNSKEYs(h, c, o, f, "CDNSKEY") 1476 if r != nil { 1477 return &CDNSKEY{*r.(*DNSKEY)}, e, s 1478 } 1479 return nil, e, s 1480} 1481 1482func setRKEY(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { 1483 rr := new(RKEY) 1484 rr.Hdr = h 1485 1486 l := <-c 1487 if l.length == 0 { // dynamic update rr. 1488 return rr, nil, l.comment 1489 } 1490 1491 i, e := strconv.ParseUint(l.token, 10, 16) 1492 if e != nil || l.err { 1493 return nil, &ParseError{f, "bad RKEY Flags", l}, "" 1494 } 1495 rr.Flags = uint16(i) 1496 <-c // zBlank 1497 l = <-c // zString 1498 i, e = strconv.ParseUint(l.token, 10, 8) 1499 if e != nil || l.err { 1500 return nil, &ParseError{f, "bad RKEY Protocol", l}, "" 1501 } 1502 rr.Protocol = uint8(i) 1503 <-c // zBlank 1504 l = <-c // zString 1505 i, e = strconv.ParseUint(l.token, 10, 8) 1506 if e != nil || l.err { 1507 return nil, &ParseError{f, "bad RKEY Algorithm", l}, "" 1508 } 1509 rr.Algorithm = uint8(i) 1510 s, e1, c1 := endingToString(c, "bad RKEY PublicKey", f) 1511 if e1 != nil { 1512 return nil, e1, c1 1513 } 1514 rr.PublicKey = s 1515 return rr, nil, c1 1516} 1517 1518func setEID(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { 1519 rr := new(EID) 1520 rr.Hdr = h 1521 s, e, c1 := endingToString(c, "bad EID Endpoint", f) 1522 if e != nil { 1523 return nil, e, c1 1524 } 1525 rr.Endpoint = s 1526 return rr, nil, c1 1527} 1528 1529func setNIMLOC(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { 1530 rr := new(NIMLOC) 1531 rr.Hdr = h 1532 s, e, c1 := endingToString(c, "bad NIMLOC Locator", f) 1533 if e != nil { 1534 return nil, e, c1 1535 } 1536 rr.Locator = s 1537 return rr, nil, c1 1538} 1539 1540func setGPOS(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { 1541 rr := new(GPOS) 1542 rr.Hdr = h 1543 1544 l := <-c 1545 if l.length == 0 { // dynamic update rr. 1546 return rr, nil, "" 1547 } 1548 1549 _, e := strconv.ParseFloat(l.token, 64) 1550 if e != nil || l.err { 1551 return nil, &ParseError{f, "bad GPOS Longitude", l}, "" 1552 } 1553 rr.Longitude = l.token 1554 <-c // zBlank 1555 l = <-c 1556 _, e = strconv.ParseFloat(l.token, 64) 1557 if e != nil || l.err { 1558 return nil, &ParseError{f, "bad GPOS Latitude", l}, "" 1559 } 1560 rr.Latitude = l.token 1561 <-c // zBlank 1562 l = <-c 1563 _, e = strconv.ParseFloat(l.token, 64) 1564 if e != nil || l.err { 1565 return nil, &ParseError{f, "bad GPOS Altitude", l}, "" 1566 } 1567 rr.Altitude = l.token 1568 return rr, nil, "" 1569} 1570 1571func setDSs(h RR_Header, c chan lex, o, f, typ string) (RR, *ParseError, string) { 1572 rr := new(DS) 1573 rr.Hdr = h 1574 1575 l := <-c 1576 if l.length == 0 { // dynamic update rr. 1577 return rr, nil, l.comment 1578 } 1579 1580 i, e := strconv.ParseUint(l.token, 10, 16) 1581 if e != nil || l.err { 1582 return nil, &ParseError{f, "bad " + typ + " KeyTag", l}, "" 1583 } 1584 rr.KeyTag = uint16(i) 1585 <-c // zBlank 1586 l = <-c 1587 if i, e = strconv.ParseUint(l.token, 10, 8); e != nil { 1588 i, ok := StringToAlgorithm[l.tokenUpper] 1589 if !ok || l.err { 1590 return nil, &ParseError{f, "bad " + typ + " Algorithm", l}, "" 1591 } 1592 rr.Algorithm = i 1593 } else { 1594 rr.Algorithm = uint8(i) 1595 } 1596 <-c // zBlank 1597 l = <-c 1598 i, e = strconv.ParseUint(l.token, 10, 8) 1599 if e != nil || l.err { 1600 return nil, &ParseError{f, "bad " + typ + " DigestType", l}, "" 1601 } 1602 rr.DigestType = uint8(i) 1603 s, e1, c1 := endingToString(c, "bad "+typ+" Digest", f) 1604 if e1 != nil { 1605 return nil, e1, c1 1606 } 1607 rr.Digest = s 1608 return rr, nil, c1 1609} 1610 1611func setDS(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { 1612 r, e, s := setDSs(h, c, o, f, "DS") 1613 return r, e, s 1614} 1615 1616func setDLV(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { 1617 r, e, s := setDSs(h, c, o, f, "DLV") 1618 if r != nil { 1619 return &DLV{*r.(*DS)}, e, s 1620 } 1621 return nil, e, s 1622} 1623 1624func setCDS(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { 1625 r, e, s := setDSs(h, c, o, f, "CDS") 1626 if r != nil { 1627 return &CDS{*r.(*DS)}, e, s 1628 } 1629 return nil, e, s 1630} 1631 1632func setTA(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { 1633 rr := new(TA) 1634 rr.Hdr = h 1635 1636 l := <-c 1637 if l.length == 0 { // dynamic update rr. 1638 return rr, nil, l.comment 1639 } 1640 1641 i, e := strconv.ParseUint(l.token, 10, 16) 1642 if e != nil || l.err { 1643 return nil, &ParseError{f, "bad TA KeyTag", l}, "" 1644 } 1645 rr.KeyTag = uint16(i) 1646 <-c // zBlank 1647 l = <-c 1648 if i, e := strconv.ParseUint(l.token, 10, 8); e != nil { 1649 i, ok := StringToAlgorithm[l.tokenUpper] 1650 if !ok || l.err { 1651 return nil, &ParseError{f, "bad TA Algorithm", l}, "" 1652 } 1653 rr.Algorithm = i 1654 } else { 1655 rr.Algorithm = uint8(i) 1656 } 1657 <-c // zBlank 1658 l = <-c 1659 i, e = strconv.ParseUint(l.token, 10, 8) 1660 if e != nil || l.err { 1661 return nil, &ParseError{f, "bad TA DigestType", l}, "" 1662 } 1663 rr.DigestType = uint8(i) 1664 s, e, c1 := endingToString(c, "bad TA Digest", f) 1665 if e != nil { 1666 return nil, e.(*ParseError), c1 1667 } 1668 rr.Digest = s 1669 return rr, nil, c1 1670} 1671 1672func setTLSA(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { 1673 rr := new(TLSA) 1674 rr.Hdr = h 1675 1676 l := <-c 1677 if l.length == 0 { // dynamic update rr. 1678 return rr, nil, l.comment 1679 } 1680 1681 i, e := strconv.ParseUint(l.token, 10, 8) 1682 if e != nil || l.err { 1683 return nil, &ParseError{f, "bad TLSA Usage", l}, "" 1684 } 1685 rr.Usage = uint8(i) 1686 <-c // zBlank 1687 l = <-c 1688 i, e = strconv.ParseUint(l.token, 10, 8) 1689 if e != nil || l.err { 1690 return nil, &ParseError{f, "bad TLSA Selector", l}, "" 1691 } 1692 rr.Selector = uint8(i) 1693 <-c // zBlank 1694 l = <-c 1695 i, e = strconv.ParseUint(l.token, 10, 8) 1696 if e != nil || l.err { 1697 return nil, &ParseError{f, "bad TLSA MatchingType", l}, "" 1698 } 1699 rr.MatchingType = uint8(i) 1700 // So this needs be e2 (i.e. different than e), because...??t 1701 s, e2, c1 := endingToString(c, "bad TLSA Certificate", f) 1702 if e2 != nil { 1703 return nil, e2, c1 1704 } 1705 rr.Certificate = s 1706 return rr, nil, c1 1707} 1708 1709func setSMIMEA(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { 1710 rr := new(SMIMEA) 1711 rr.Hdr = h 1712 1713 l := <-c 1714 if l.length == 0 { // dynamic update rr. 1715 return rr, nil, l.comment 1716 } 1717 1718 i, e := strconv.ParseUint(l.token, 10, 8) 1719 if e != nil || l.err { 1720 return nil, &ParseError{f, "bad SMIMEA Usage", l}, "" 1721 } 1722 rr.Usage = uint8(i) 1723 <-c // zBlank 1724 l = <-c 1725 i, e = strconv.ParseUint(l.token, 10, 8) 1726 if e != nil || l.err { 1727 return nil, &ParseError{f, "bad SMIMEA Selector", l}, "" 1728 } 1729 rr.Selector = uint8(i) 1730 <-c // zBlank 1731 l = <-c 1732 i, e = strconv.ParseUint(l.token, 10, 8) 1733 if e != nil || l.err { 1734 return nil, &ParseError{f, "bad SMIMEA MatchingType", l}, "" 1735 } 1736 rr.MatchingType = uint8(i) 1737 // So this needs be e2 (i.e. different than e), because...??t 1738 s, e2, c1 := endingToString(c, "bad SMIMEA Certificate", f) 1739 if e2 != nil { 1740 return nil, e2, c1 1741 } 1742 rr.Certificate = s 1743 return rr, nil, c1 1744} 1745 1746func setRFC3597(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { 1747 rr := new(RFC3597) 1748 rr.Hdr = h 1749 1750 l := <-c 1751 if l.token != "\\#" { 1752 return nil, &ParseError{f, "bad RFC3597 Rdata", l}, "" 1753 } 1754 1755 <-c // zBlank 1756 l = <-c 1757 rdlength, e := strconv.Atoi(l.token) 1758 if e != nil || l.err { 1759 return nil, &ParseError{f, "bad RFC3597 Rdata ", l}, "" 1760 } 1761 1762 s, e1, c1 := endingToString(c, "bad RFC3597 Rdata", f) 1763 if e1 != nil { 1764 return nil, e1, c1 1765 } 1766 if rdlength*2 != len(s) { 1767 return nil, &ParseError{f, "bad RFC3597 Rdata", l}, "" 1768 } 1769 rr.Rdata = s 1770 return rr, nil, c1 1771} 1772 1773func setSPF(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { 1774 rr := new(SPF) 1775 rr.Hdr = h 1776 1777 s, e, c1 := endingToTxtSlice(c, "bad SPF Txt", f) 1778 if e != nil { 1779 return nil, e, "" 1780 } 1781 rr.Txt = s 1782 return rr, nil, c1 1783} 1784 1785func setAVC(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { 1786 rr := new(AVC) 1787 rr.Hdr = h 1788 1789 s, e, c1 := endingToTxtSlice(c, "bad AVC Txt", f) 1790 if e != nil { 1791 return nil, e, "" 1792 } 1793 rr.Txt = s 1794 return rr, nil, c1 1795} 1796 1797func setTXT(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { 1798 rr := new(TXT) 1799 rr.Hdr = h 1800 1801 // no zBlank reading here, because all this rdata is TXT 1802 s, e, c1 := endingToTxtSlice(c, "bad TXT Txt", f) 1803 if e != nil { 1804 return nil, e, "" 1805 } 1806 rr.Txt = s 1807 return rr, nil, c1 1808} 1809 1810// identical to setTXT 1811func setNINFO(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { 1812 rr := new(NINFO) 1813 rr.Hdr = h 1814 1815 s, e, c1 := endingToTxtSlice(c, "bad NINFO ZSData", f) 1816 if e != nil { 1817 return nil, e, "" 1818 } 1819 rr.ZSData = s 1820 return rr, nil, c1 1821} 1822 1823func setURI(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { 1824 rr := new(URI) 1825 rr.Hdr = h 1826 1827 l := <-c 1828 if l.length == 0 { // dynamic update rr. 1829 return rr, nil, "" 1830 } 1831 1832 i, e := strconv.ParseUint(l.token, 10, 16) 1833 if e != nil || l.err { 1834 return nil, &ParseError{f, "bad URI Priority", l}, "" 1835 } 1836 rr.Priority = uint16(i) 1837 <-c // zBlank 1838 l = <-c 1839 i, e = strconv.ParseUint(l.token, 10, 16) 1840 if e != nil || l.err { 1841 return nil, &ParseError{f, "bad URI Weight", l}, "" 1842 } 1843 rr.Weight = uint16(i) 1844 1845 <-c // zBlank 1846 s, err, c1 := endingToTxtSlice(c, "bad URI Target", f) 1847 if err != nil { 1848 return nil, err, "" 1849 } 1850 if len(s) != 1 { 1851 return nil, &ParseError{f, "bad URI Target", l}, "" 1852 } 1853 rr.Target = s[0] 1854 return rr, nil, c1 1855} 1856 1857func setDHCID(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { 1858 // awesome record to parse! 1859 rr := new(DHCID) 1860 rr.Hdr = h 1861 1862 s, e, c1 := endingToString(c, "bad DHCID Digest", f) 1863 if e != nil { 1864 return nil, e, c1 1865 } 1866 rr.Digest = s 1867 return rr, nil, c1 1868} 1869 1870func setNID(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { 1871 rr := new(NID) 1872 rr.Hdr = h 1873 1874 l := <-c 1875 if l.length == 0 { // dynamic update rr. 1876 return rr, nil, "" 1877 } 1878 1879 i, e := strconv.ParseUint(l.token, 10, 16) 1880 if e != nil || l.err { 1881 return nil, &ParseError{f, "bad NID Preference", l}, "" 1882 } 1883 rr.Preference = uint16(i) 1884 <-c // zBlank 1885 l = <-c // zString 1886 u, err := stringToNodeID(l) 1887 if err != nil || l.err { 1888 return nil, err, "" 1889 } 1890 rr.NodeID = u 1891 return rr, nil, "" 1892} 1893 1894func setL32(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { 1895 rr := new(L32) 1896 rr.Hdr = h 1897 1898 l := <-c 1899 if l.length == 0 { // dynamic update rr. 1900 return rr, nil, "" 1901 } 1902 1903 i, e := strconv.ParseUint(l.token, 10, 16) 1904 if e != nil || l.err { 1905 return nil, &ParseError{f, "bad L32 Preference", l}, "" 1906 } 1907 rr.Preference = uint16(i) 1908 <-c // zBlank 1909 l = <-c // zString 1910 rr.Locator32 = net.ParseIP(l.token) 1911 if rr.Locator32 == nil || l.err { 1912 return nil, &ParseError{f, "bad L32 Locator", l}, "" 1913 } 1914 return rr, nil, "" 1915} 1916 1917func setLP(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { 1918 rr := new(LP) 1919 rr.Hdr = h 1920 1921 l := <-c 1922 if l.length == 0 { // dynamic update rr. 1923 return rr, nil, "" 1924 } 1925 1926 i, e := strconv.ParseUint(l.token, 10, 16) 1927 if e != nil || l.err { 1928 return nil, &ParseError{f, "bad LP Preference", l}, "" 1929 } 1930 rr.Preference = uint16(i) 1931 1932 <-c // zBlank 1933 l = <-c // zString 1934 rr.Fqdn = l.token 1935 name, nameOk := toAbsoluteName(l.token, o) 1936 if l.err || !nameOk { 1937 return nil, &ParseError{f, "bad LP Fqdn", l}, "" 1938 } 1939 rr.Fqdn = name 1940 1941 return rr, nil, "" 1942} 1943 1944func setL64(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { 1945 rr := new(L64) 1946 rr.Hdr = h 1947 1948 l := <-c 1949 if l.length == 0 { // dynamic update rr. 1950 return rr, nil, "" 1951 } 1952 1953 i, e := strconv.ParseUint(l.token, 10, 16) 1954 if e != nil || l.err { 1955 return nil, &ParseError{f, "bad L64 Preference", l}, "" 1956 } 1957 rr.Preference = uint16(i) 1958 <-c // zBlank 1959 l = <-c // zString 1960 u, err := stringToNodeID(l) 1961 if err != nil || l.err { 1962 return nil, err, "" 1963 } 1964 rr.Locator64 = u 1965 return rr, nil, "" 1966} 1967 1968func setUID(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { 1969 rr := new(UID) 1970 rr.Hdr = h 1971 1972 l := <-c 1973 if l.length == 0 { // dynamic update rr. 1974 return rr, nil, "" 1975 } 1976 1977 i, e := strconv.ParseUint(l.token, 10, 32) 1978 if e != nil || l.err { 1979 return nil, &ParseError{f, "bad UID Uid", l}, "" 1980 } 1981 rr.Uid = uint32(i) 1982 return rr, nil, "" 1983} 1984 1985func setGID(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { 1986 rr := new(GID) 1987 rr.Hdr = h 1988 1989 l := <-c 1990 if l.length == 0 { // dynamic update rr. 1991 return rr, nil, "" 1992 } 1993 1994 i, e := strconv.ParseUint(l.token, 10, 32) 1995 if e != nil || l.err { 1996 return nil, &ParseError{f, "bad GID Gid", l}, "" 1997 } 1998 rr.Gid = uint32(i) 1999 return rr, nil, "" 2000} 2001 2002func setUINFO(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { 2003 rr := new(UINFO) 2004 rr.Hdr = h 2005 2006 s, e, c1 := endingToTxtSlice(c, "bad UINFO Uinfo", f) 2007 if e != nil { 2008 return nil, e, c1 2009 } 2010 if ln := len(s); ln == 0 { 2011 return rr, nil, c1 2012 } 2013 rr.Uinfo = s[0] // silently discard anything after the first character-string 2014 return rr, nil, c1 2015} 2016 2017func setPX(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { 2018 rr := new(PX) 2019 rr.Hdr = h 2020 2021 l := <-c 2022 if l.length == 0 { // dynamic update rr. 2023 return rr, nil, "" 2024 } 2025 2026 i, e := strconv.ParseUint(l.token, 10, 16) 2027 if e != nil || l.err { 2028 return nil, &ParseError{f, "bad PX Preference", l}, "" 2029 } 2030 rr.Preference = uint16(i) 2031 2032 <-c // zBlank 2033 l = <-c // zString 2034 rr.Map822 = l.token 2035 map822, map822Ok := toAbsoluteName(l.token, o) 2036 if l.err || !map822Ok { 2037 return nil, &ParseError{f, "bad PX Map822", l}, "" 2038 } 2039 rr.Map822 = map822 2040 2041 <-c // zBlank 2042 l = <-c // zString 2043 rr.Mapx400 = l.token 2044 mapx400, mapx400Ok := toAbsoluteName(l.token, o) 2045 if l.err || !mapx400Ok { 2046 return nil, &ParseError{f, "bad PX Mapx400", l}, "" 2047 } 2048 rr.Mapx400 = mapx400 2049 2050 return rr, nil, "" 2051} 2052 2053func setCAA(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { 2054 rr := new(CAA) 2055 rr.Hdr = h 2056 2057 l := <-c 2058 if l.length == 0 { // dynamic update rr. 2059 return rr, nil, l.comment 2060 } 2061 2062 i, err := strconv.ParseUint(l.token, 10, 8) 2063 if err != nil || l.err { 2064 return nil, &ParseError{f, "bad CAA Flag", l}, "" 2065 } 2066 rr.Flag = uint8(i) 2067 2068 <-c // zBlank 2069 l = <-c // zString 2070 if l.value != zString { 2071 return nil, &ParseError{f, "bad CAA Tag", l}, "" 2072 } 2073 rr.Tag = l.token 2074 2075 <-c // zBlank 2076 s, e, c1 := endingToTxtSlice(c, "bad CAA Value", f) 2077 if e != nil { 2078 return nil, e, "" 2079 } 2080 if len(s) != 1 { 2081 return nil, &ParseError{f, "bad CAA Value", l}, "" 2082 } 2083 rr.Value = s[0] 2084 return rr, nil, c1 2085} 2086 2087func setTKEY(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { 2088 rr := new(TKEY) 2089 rr.Hdr = h 2090 2091 l := <-c 2092 2093 // Algorithm 2094 if l.value != zString { 2095 return nil, &ParseError{f, "bad TKEY algorithm", l}, "" 2096 } 2097 rr.Algorithm = l.token 2098 <-c // zBlank 2099 2100 // Get the key length and key values 2101 l = <-c 2102 i, err := strconv.ParseUint(l.token, 10, 8) 2103 if err != nil || l.err { 2104 return nil, &ParseError{f, "bad TKEY key length", l}, "" 2105 } 2106 rr.KeySize = uint16(i) 2107 <-c // zBlank 2108 l = <-c 2109 if l.value != zString { 2110 return nil, &ParseError{f, "bad TKEY key", l}, "" 2111 } 2112 rr.Key = l.token 2113 <-c // zBlank 2114 2115 // Get the otherdata length and string data 2116 l = <-c 2117 i, err = strconv.ParseUint(l.token, 10, 8) 2118 if err != nil || l.err { 2119 return nil, &ParseError{f, "bad TKEY otherdata length", l}, "" 2120 } 2121 rr.OtherLen = uint16(i) 2122 <-c // zBlank 2123 l = <-c 2124 if l.value != zString { 2125 return nil, &ParseError{f, "bad TKEY otherday", l}, "" 2126 } 2127 rr.OtherData = l.token 2128 2129 return rr, nil, "" 2130} 2131 2132var typeToparserFunc = map[uint16]parserFunc{ 2133 TypeAAAA: {setAAAA, false}, 2134 TypeAFSDB: {setAFSDB, false}, 2135 TypeA: {setA, false}, 2136 TypeCAA: {setCAA, true}, 2137 TypeCDS: {setCDS, true}, 2138 TypeCDNSKEY: {setCDNSKEY, true}, 2139 TypeCERT: {setCERT, true}, 2140 TypeCNAME: {setCNAME, false}, 2141 TypeCSYNC: {setCSYNC, true}, 2142 TypeDHCID: {setDHCID, true}, 2143 TypeDLV: {setDLV, true}, 2144 TypeDNAME: {setDNAME, false}, 2145 TypeKEY: {setKEY, true}, 2146 TypeDNSKEY: {setDNSKEY, true}, 2147 TypeDS: {setDS, true}, 2148 TypeEID: {setEID, true}, 2149 TypeEUI48: {setEUI48, false}, 2150 TypeEUI64: {setEUI64, false}, 2151 TypeGID: {setGID, false}, 2152 TypeGPOS: {setGPOS, false}, 2153 TypeHINFO: {setHINFO, true}, 2154 TypeHIP: {setHIP, true}, 2155 TypeKX: {setKX, false}, 2156 TypeL32: {setL32, false}, 2157 TypeL64: {setL64, false}, 2158 TypeLOC: {setLOC, true}, 2159 TypeLP: {setLP, false}, 2160 TypeMB: {setMB, false}, 2161 TypeMD: {setMD, false}, 2162 TypeMF: {setMF, false}, 2163 TypeMG: {setMG, false}, 2164 TypeMINFO: {setMINFO, false}, 2165 TypeMR: {setMR, false}, 2166 TypeMX: {setMX, false}, 2167 TypeNAPTR: {setNAPTR, false}, 2168 TypeNID: {setNID, false}, 2169 TypeNIMLOC: {setNIMLOC, true}, 2170 TypeNINFO: {setNINFO, true}, 2171 TypeNSAPPTR: {setNSAPPTR, false}, 2172 TypeNSEC3PARAM: {setNSEC3PARAM, false}, 2173 TypeNSEC3: {setNSEC3, true}, 2174 TypeNSEC: {setNSEC, true}, 2175 TypeNS: {setNS, false}, 2176 TypeOPENPGPKEY: {setOPENPGPKEY, true}, 2177 TypePTR: {setPTR, false}, 2178 TypePX: {setPX, false}, 2179 TypeSIG: {setSIG, true}, 2180 TypeRKEY: {setRKEY, true}, 2181 TypeRP: {setRP, false}, 2182 TypeRRSIG: {setRRSIG, true}, 2183 TypeRT: {setRT, false}, 2184 TypeSMIMEA: {setSMIMEA, true}, 2185 TypeSOA: {setSOA, false}, 2186 TypeSPF: {setSPF, true}, 2187 TypeAVC: {setAVC, true}, 2188 TypeSRV: {setSRV, false}, 2189 TypeSSHFP: {setSSHFP, true}, 2190 TypeTALINK: {setTALINK, false}, 2191 TypeTA: {setTA, true}, 2192 TypeTLSA: {setTLSA, true}, 2193 TypeTXT: {setTXT, true}, 2194 TypeUID: {setUID, false}, 2195 TypeUINFO: {setUINFO, true}, 2196 TypeURI: {setURI, true}, 2197 TypeX25: {setX25, false}, 2198 TypeTKEY: {setTKEY, true}, 2199} 2200