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 if l.token != "-" { 1259 rr.SaltLength = uint8(len(l.token)) / 2 1260 rr.Salt = l.token 1261 } 1262 1263 <-c 1264 l = <-c 1265 if len(l.token) == 0 || l.err { 1266 return nil, &ParseError{f, "bad NSEC3 NextDomain", l}, "" 1267 } 1268 rr.HashLength = 20 // Fix for NSEC3 (sha1 160 bits) 1269 rr.NextDomain = l.token 1270 1271 rr.TypeBitMap = make([]uint16, 0) 1272 var ( 1273 k uint16 1274 ok bool 1275 ) 1276 l = <-c 1277 for l.value != zNewline && l.value != zEOF { 1278 switch l.value { 1279 case zBlank: 1280 // Ok 1281 case zString: 1282 if k, ok = StringToType[l.tokenUpper]; !ok { 1283 if k, ok = typeToInt(l.tokenUpper); !ok { 1284 return nil, &ParseError{f, "bad NSEC3 TypeBitMap", l}, "" 1285 } 1286 } 1287 rr.TypeBitMap = append(rr.TypeBitMap, k) 1288 default: 1289 return nil, &ParseError{f, "bad NSEC3 TypeBitMap", l}, "" 1290 } 1291 l = <-c 1292 } 1293 return rr, nil, l.comment 1294} 1295 1296func setNSEC3PARAM(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { 1297 rr := new(NSEC3PARAM) 1298 rr.Hdr = h 1299 1300 l := <-c 1301 if l.length == 0 { // dynamic update rr. 1302 return rr, nil, "" 1303 } 1304 1305 i, e := strconv.ParseUint(l.token, 10, 8) 1306 if e != nil || l.err { 1307 return nil, &ParseError{f, "bad NSEC3PARAM Hash", l}, "" 1308 } 1309 rr.Hash = uint8(i) 1310 <-c // zBlank 1311 l = <-c 1312 i, e = strconv.ParseUint(l.token, 10, 8) 1313 if e != nil || l.err { 1314 return nil, &ParseError{f, "bad NSEC3PARAM Flags", l}, "" 1315 } 1316 rr.Flags = uint8(i) 1317 <-c // zBlank 1318 l = <-c 1319 i, e = strconv.ParseUint(l.token, 10, 16) 1320 if e != nil || l.err { 1321 return nil, &ParseError{f, "bad NSEC3PARAM Iterations", l}, "" 1322 } 1323 rr.Iterations = uint16(i) 1324 <-c 1325 l = <-c 1326 if l.token != "-" { 1327 rr.SaltLength = uint8(len(l.token)) 1328 rr.Salt = l.token 1329 } 1330 return rr, nil, "" 1331} 1332 1333func setEUI48(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { 1334 rr := new(EUI48) 1335 rr.Hdr = h 1336 1337 l := <-c 1338 if l.length == 0 { // dynamic update rr. 1339 return rr, nil, "" 1340 } 1341 1342 if l.length != 17 || l.err { 1343 return nil, &ParseError{f, "bad EUI48 Address", l}, "" 1344 } 1345 addr := make([]byte, 12) 1346 dash := 0 1347 for i := 0; i < 10; i += 2 { 1348 addr[i] = l.token[i+dash] 1349 addr[i+1] = l.token[i+1+dash] 1350 dash++ 1351 if l.token[i+1+dash] != '-' { 1352 return nil, &ParseError{f, "bad EUI48 Address", l}, "" 1353 } 1354 } 1355 addr[10] = l.token[15] 1356 addr[11] = l.token[16] 1357 1358 i, e := strconv.ParseUint(string(addr), 16, 48) 1359 if e != nil { 1360 return nil, &ParseError{f, "bad EUI48 Address", l}, "" 1361 } 1362 rr.Address = i 1363 return rr, nil, "" 1364} 1365 1366func setEUI64(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { 1367 rr := new(EUI64) 1368 rr.Hdr = h 1369 1370 l := <-c 1371 if l.length == 0 { // dynamic update rr. 1372 return rr, nil, "" 1373 } 1374 1375 if l.length != 23 || l.err { 1376 return nil, &ParseError{f, "bad EUI64 Address", l}, "" 1377 } 1378 addr := make([]byte, 16) 1379 dash := 0 1380 for i := 0; i < 14; i += 2 { 1381 addr[i] = l.token[i+dash] 1382 addr[i+1] = l.token[i+1+dash] 1383 dash++ 1384 if l.token[i+1+dash] != '-' { 1385 return nil, &ParseError{f, "bad EUI64 Address", l}, "" 1386 } 1387 } 1388 addr[14] = l.token[21] 1389 addr[15] = l.token[22] 1390 1391 i, e := strconv.ParseUint(string(addr), 16, 64) 1392 if e != nil { 1393 return nil, &ParseError{f, "bad EUI68 Address", l}, "" 1394 } 1395 rr.Address = uint64(i) 1396 return rr, nil, "" 1397} 1398 1399func setSSHFP(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { 1400 rr := new(SSHFP) 1401 rr.Hdr = h 1402 1403 l := <-c 1404 if l.length == 0 { // dynamic update rr. 1405 return rr, nil, "" 1406 } 1407 1408 i, e := strconv.ParseUint(l.token, 10, 8) 1409 if e != nil || l.err { 1410 return nil, &ParseError{f, "bad SSHFP Algorithm", l}, "" 1411 } 1412 rr.Algorithm = uint8(i) 1413 <-c // zBlank 1414 l = <-c 1415 i, e = strconv.ParseUint(l.token, 10, 8) 1416 if e != nil || l.err { 1417 return nil, &ParseError{f, "bad SSHFP Type", l}, "" 1418 } 1419 rr.Type = uint8(i) 1420 <-c // zBlank 1421 s, e1, c1 := endingToString(c, "bad SSHFP Fingerprint", f) 1422 if e1 != nil { 1423 return nil, e1, c1 1424 } 1425 rr.FingerPrint = s 1426 return rr, nil, "" 1427} 1428 1429func setDNSKEYs(h RR_Header, c chan lex, o, f, typ string) (RR, *ParseError, string) { 1430 rr := new(DNSKEY) 1431 rr.Hdr = h 1432 1433 l := <-c 1434 if l.length == 0 { // dynamic update rr. 1435 return rr, nil, l.comment 1436 } 1437 1438 i, e := strconv.ParseUint(l.token, 10, 16) 1439 if e != nil || l.err { 1440 return nil, &ParseError{f, "bad " + typ + " Flags", l}, "" 1441 } 1442 rr.Flags = uint16(i) 1443 <-c // zBlank 1444 l = <-c // zString 1445 i, e = strconv.ParseUint(l.token, 10, 8) 1446 if e != nil || l.err { 1447 return nil, &ParseError{f, "bad " + typ + " Protocol", l}, "" 1448 } 1449 rr.Protocol = uint8(i) 1450 <-c // zBlank 1451 l = <-c // zString 1452 i, e = strconv.ParseUint(l.token, 10, 8) 1453 if e != nil || l.err { 1454 return nil, &ParseError{f, "bad " + typ + " Algorithm", l}, "" 1455 } 1456 rr.Algorithm = uint8(i) 1457 s, e1, c1 := endingToString(c, "bad "+typ+" PublicKey", f) 1458 if e1 != nil { 1459 return nil, e1, c1 1460 } 1461 rr.PublicKey = s 1462 return rr, nil, c1 1463} 1464 1465func setKEY(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { 1466 r, e, s := setDNSKEYs(h, c, o, f, "KEY") 1467 if r != nil { 1468 return &KEY{*r.(*DNSKEY)}, e, s 1469 } 1470 return nil, e, s 1471} 1472 1473func setDNSKEY(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { 1474 r, e, s := setDNSKEYs(h, c, o, f, "DNSKEY") 1475 return r, e, s 1476} 1477 1478func setCDNSKEY(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { 1479 r, e, s := setDNSKEYs(h, c, o, f, "CDNSKEY") 1480 if r != nil { 1481 return &CDNSKEY{*r.(*DNSKEY)}, e, s 1482 } 1483 return nil, e, s 1484} 1485 1486func setRKEY(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { 1487 rr := new(RKEY) 1488 rr.Hdr = h 1489 1490 l := <-c 1491 if l.length == 0 { // dynamic update rr. 1492 return rr, nil, l.comment 1493 } 1494 1495 i, e := strconv.ParseUint(l.token, 10, 16) 1496 if e != nil || l.err { 1497 return nil, &ParseError{f, "bad RKEY Flags", l}, "" 1498 } 1499 rr.Flags = uint16(i) 1500 <-c // zBlank 1501 l = <-c // zString 1502 i, e = strconv.ParseUint(l.token, 10, 8) 1503 if e != nil || l.err { 1504 return nil, &ParseError{f, "bad RKEY Protocol", l}, "" 1505 } 1506 rr.Protocol = uint8(i) 1507 <-c // zBlank 1508 l = <-c // zString 1509 i, e = strconv.ParseUint(l.token, 10, 8) 1510 if e != nil || l.err { 1511 return nil, &ParseError{f, "bad RKEY Algorithm", l}, "" 1512 } 1513 rr.Algorithm = uint8(i) 1514 s, e1, c1 := endingToString(c, "bad RKEY PublicKey", f) 1515 if e1 != nil { 1516 return nil, e1, c1 1517 } 1518 rr.PublicKey = s 1519 return rr, nil, c1 1520} 1521 1522func setEID(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { 1523 rr := new(EID) 1524 rr.Hdr = h 1525 s, e, c1 := endingToString(c, "bad EID Endpoint", f) 1526 if e != nil { 1527 return nil, e, c1 1528 } 1529 rr.Endpoint = s 1530 return rr, nil, c1 1531} 1532 1533func setNIMLOC(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { 1534 rr := new(NIMLOC) 1535 rr.Hdr = h 1536 s, e, c1 := endingToString(c, "bad NIMLOC Locator", f) 1537 if e != nil { 1538 return nil, e, c1 1539 } 1540 rr.Locator = s 1541 return rr, nil, c1 1542} 1543 1544func setGPOS(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { 1545 rr := new(GPOS) 1546 rr.Hdr = h 1547 1548 l := <-c 1549 if l.length == 0 { // dynamic update rr. 1550 return rr, nil, "" 1551 } 1552 1553 _, e := strconv.ParseFloat(l.token, 64) 1554 if e != nil || l.err { 1555 return nil, &ParseError{f, "bad GPOS Longitude", l}, "" 1556 } 1557 rr.Longitude = l.token 1558 <-c // zBlank 1559 l = <-c 1560 _, e = strconv.ParseFloat(l.token, 64) 1561 if e != nil || l.err { 1562 return nil, &ParseError{f, "bad GPOS Latitude", l}, "" 1563 } 1564 rr.Latitude = l.token 1565 <-c // zBlank 1566 l = <-c 1567 _, e = strconv.ParseFloat(l.token, 64) 1568 if e != nil || l.err { 1569 return nil, &ParseError{f, "bad GPOS Altitude", l}, "" 1570 } 1571 rr.Altitude = l.token 1572 return rr, nil, "" 1573} 1574 1575func setDSs(h RR_Header, c chan lex, o, f, typ string) (RR, *ParseError, string) { 1576 rr := new(DS) 1577 rr.Hdr = h 1578 1579 l := <-c 1580 if l.length == 0 { // dynamic update rr. 1581 return rr, nil, l.comment 1582 } 1583 1584 i, e := strconv.ParseUint(l.token, 10, 16) 1585 if e != nil || l.err { 1586 return nil, &ParseError{f, "bad " + typ + " KeyTag", l}, "" 1587 } 1588 rr.KeyTag = uint16(i) 1589 <-c // zBlank 1590 l = <-c 1591 if i, e = strconv.ParseUint(l.token, 10, 8); e != nil { 1592 i, ok := StringToAlgorithm[l.tokenUpper] 1593 if !ok || l.err { 1594 return nil, &ParseError{f, "bad " + typ + " Algorithm", l}, "" 1595 } 1596 rr.Algorithm = i 1597 } else { 1598 rr.Algorithm = uint8(i) 1599 } 1600 <-c // zBlank 1601 l = <-c 1602 i, e = strconv.ParseUint(l.token, 10, 8) 1603 if e != nil || l.err { 1604 return nil, &ParseError{f, "bad " + typ + " DigestType", l}, "" 1605 } 1606 rr.DigestType = uint8(i) 1607 s, e1, c1 := endingToString(c, "bad "+typ+" Digest", f) 1608 if e1 != nil { 1609 return nil, e1, c1 1610 } 1611 rr.Digest = s 1612 return rr, nil, c1 1613} 1614 1615func setDS(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { 1616 r, e, s := setDSs(h, c, o, f, "DS") 1617 return r, e, s 1618} 1619 1620func setDLV(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { 1621 r, e, s := setDSs(h, c, o, f, "DLV") 1622 if r != nil { 1623 return &DLV{*r.(*DS)}, e, s 1624 } 1625 return nil, e, s 1626} 1627 1628func setCDS(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { 1629 r, e, s := setDSs(h, c, o, f, "CDS") 1630 if r != nil { 1631 return &CDS{*r.(*DS)}, e, s 1632 } 1633 return nil, e, s 1634} 1635 1636func setTA(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { 1637 rr := new(TA) 1638 rr.Hdr = h 1639 1640 l := <-c 1641 if l.length == 0 { // dynamic update rr. 1642 return rr, nil, l.comment 1643 } 1644 1645 i, e := strconv.ParseUint(l.token, 10, 16) 1646 if e != nil || l.err { 1647 return nil, &ParseError{f, "bad TA KeyTag", l}, "" 1648 } 1649 rr.KeyTag = uint16(i) 1650 <-c // zBlank 1651 l = <-c 1652 if i, e := strconv.ParseUint(l.token, 10, 8); e != nil { 1653 i, ok := StringToAlgorithm[l.tokenUpper] 1654 if !ok || l.err { 1655 return nil, &ParseError{f, "bad TA Algorithm", l}, "" 1656 } 1657 rr.Algorithm = i 1658 } else { 1659 rr.Algorithm = uint8(i) 1660 } 1661 <-c // zBlank 1662 l = <-c 1663 i, e = strconv.ParseUint(l.token, 10, 8) 1664 if e != nil || l.err { 1665 return nil, &ParseError{f, "bad TA DigestType", l}, "" 1666 } 1667 rr.DigestType = uint8(i) 1668 s, e, c1 := endingToString(c, "bad TA Digest", f) 1669 if e != nil { 1670 return nil, e.(*ParseError), c1 1671 } 1672 rr.Digest = s 1673 return rr, nil, c1 1674} 1675 1676func setTLSA(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { 1677 rr := new(TLSA) 1678 rr.Hdr = h 1679 1680 l := <-c 1681 if l.length == 0 { // dynamic update rr. 1682 return rr, nil, l.comment 1683 } 1684 1685 i, e := strconv.ParseUint(l.token, 10, 8) 1686 if e != nil || l.err { 1687 return nil, &ParseError{f, "bad TLSA Usage", l}, "" 1688 } 1689 rr.Usage = uint8(i) 1690 <-c // zBlank 1691 l = <-c 1692 i, e = strconv.ParseUint(l.token, 10, 8) 1693 if e != nil || l.err { 1694 return nil, &ParseError{f, "bad TLSA Selector", l}, "" 1695 } 1696 rr.Selector = uint8(i) 1697 <-c // zBlank 1698 l = <-c 1699 i, e = strconv.ParseUint(l.token, 10, 8) 1700 if e != nil || l.err { 1701 return nil, &ParseError{f, "bad TLSA MatchingType", l}, "" 1702 } 1703 rr.MatchingType = uint8(i) 1704 // So this needs be e2 (i.e. different than e), because...??t 1705 s, e2, c1 := endingToString(c, "bad TLSA Certificate", f) 1706 if e2 != nil { 1707 return nil, e2, c1 1708 } 1709 rr.Certificate = s 1710 return rr, nil, c1 1711} 1712 1713func setSMIMEA(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { 1714 rr := new(SMIMEA) 1715 rr.Hdr = h 1716 1717 l := <-c 1718 if l.length == 0 { // dynamic update rr. 1719 return rr, nil, l.comment 1720 } 1721 1722 i, e := strconv.ParseUint(l.token, 10, 8) 1723 if e != nil || l.err { 1724 return nil, &ParseError{f, "bad SMIMEA Usage", l}, "" 1725 } 1726 rr.Usage = uint8(i) 1727 <-c // zBlank 1728 l = <-c 1729 i, e = strconv.ParseUint(l.token, 10, 8) 1730 if e != nil || l.err { 1731 return nil, &ParseError{f, "bad SMIMEA Selector", l}, "" 1732 } 1733 rr.Selector = uint8(i) 1734 <-c // zBlank 1735 l = <-c 1736 i, e = strconv.ParseUint(l.token, 10, 8) 1737 if e != nil || l.err { 1738 return nil, &ParseError{f, "bad SMIMEA MatchingType", l}, "" 1739 } 1740 rr.MatchingType = uint8(i) 1741 // So this needs be e2 (i.e. different than e), because...??t 1742 s, e2, c1 := endingToString(c, "bad SMIMEA Certificate", f) 1743 if e2 != nil { 1744 return nil, e2, c1 1745 } 1746 rr.Certificate = s 1747 return rr, nil, c1 1748} 1749 1750func setRFC3597(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { 1751 rr := new(RFC3597) 1752 rr.Hdr = h 1753 1754 l := <-c 1755 if l.token != "\\#" { 1756 return nil, &ParseError{f, "bad RFC3597 Rdata", l}, "" 1757 } 1758 1759 <-c // zBlank 1760 l = <-c 1761 rdlength, e := strconv.Atoi(l.token) 1762 if e != nil || l.err { 1763 return nil, &ParseError{f, "bad RFC3597 Rdata ", l}, "" 1764 } 1765 1766 s, e1, c1 := endingToString(c, "bad RFC3597 Rdata", f) 1767 if e1 != nil { 1768 return nil, e1, c1 1769 } 1770 if rdlength*2 != len(s) { 1771 return nil, &ParseError{f, "bad RFC3597 Rdata", l}, "" 1772 } 1773 rr.Rdata = s 1774 return rr, nil, c1 1775} 1776 1777func setSPF(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { 1778 rr := new(SPF) 1779 rr.Hdr = h 1780 1781 s, e, c1 := endingToTxtSlice(c, "bad SPF Txt", f) 1782 if e != nil { 1783 return nil, e, "" 1784 } 1785 rr.Txt = s 1786 return rr, nil, c1 1787} 1788 1789func setAVC(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { 1790 rr := new(AVC) 1791 rr.Hdr = h 1792 1793 s, e, c1 := endingToTxtSlice(c, "bad AVC Txt", f) 1794 if e != nil { 1795 return nil, e, "" 1796 } 1797 rr.Txt = s 1798 return rr, nil, c1 1799} 1800 1801func setTXT(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { 1802 rr := new(TXT) 1803 rr.Hdr = h 1804 1805 // no zBlank reading here, because all this rdata is TXT 1806 s, e, c1 := endingToTxtSlice(c, "bad TXT Txt", f) 1807 if e != nil { 1808 return nil, e, "" 1809 } 1810 rr.Txt = s 1811 return rr, nil, c1 1812} 1813 1814// identical to setTXT 1815func setNINFO(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { 1816 rr := new(NINFO) 1817 rr.Hdr = h 1818 1819 s, e, c1 := endingToTxtSlice(c, "bad NINFO ZSData", f) 1820 if e != nil { 1821 return nil, e, "" 1822 } 1823 rr.ZSData = s 1824 return rr, nil, c1 1825} 1826 1827func setURI(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { 1828 rr := new(URI) 1829 rr.Hdr = h 1830 1831 l := <-c 1832 if l.length == 0 { // dynamic update rr. 1833 return rr, nil, "" 1834 } 1835 1836 i, e := strconv.ParseUint(l.token, 10, 16) 1837 if e != nil || l.err { 1838 return nil, &ParseError{f, "bad URI Priority", l}, "" 1839 } 1840 rr.Priority = uint16(i) 1841 <-c // zBlank 1842 l = <-c 1843 i, e = strconv.ParseUint(l.token, 10, 16) 1844 if e != nil || l.err { 1845 return nil, &ParseError{f, "bad URI Weight", l}, "" 1846 } 1847 rr.Weight = uint16(i) 1848 1849 <-c // zBlank 1850 s, err, c1 := endingToTxtSlice(c, "bad URI Target", f) 1851 if err != nil { 1852 return nil, err, "" 1853 } 1854 if len(s) != 1 { 1855 return nil, &ParseError{f, "bad URI Target", l}, "" 1856 } 1857 rr.Target = s[0] 1858 return rr, nil, c1 1859} 1860 1861func setDHCID(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { 1862 // awesome record to parse! 1863 rr := new(DHCID) 1864 rr.Hdr = h 1865 1866 s, e, c1 := endingToString(c, "bad DHCID Digest", f) 1867 if e != nil { 1868 return nil, e, c1 1869 } 1870 rr.Digest = s 1871 return rr, nil, c1 1872} 1873 1874func setNID(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { 1875 rr := new(NID) 1876 rr.Hdr = h 1877 1878 l := <-c 1879 if l.length == 0 { // dynamic update rr. 1880 return rr, nil, "" 1881 } 1882 1883 i, e := strconv.ParseUint(l.token, 10, 16) 1884 if e != nil || l.err { 1885 return nil, &ParseError{f, "bad NID Preference", l}, "" 1886 } 1887 rr.Preference = uint16(i) 1888 <-c // zBlank 1889 l = <-c // zString 1890 u, err := stringToNodeID(l) 1891 if err != nil || l.err { 1892 return nil, err, "" 1893 } 1894 rr.NodeID = u 1895 return rr, nil, "" 1896} 1897 1898func setL32(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { 1899 rr := new(L32) 1900 rr.Hdr = h 1901 1902 l := <-c 1903 if l.length == 0 { // dynamic update rr. 1904 return rr, nil, "" 1905 } 1906 1907 i, e := strconv.ParseUint(l.token, 10, 16) 1908 if e != nil || l.err { 1909 return nil, &ParseError{f, "bad L32 Preference", l}, "" 1910 } 1911 rr.Preference = uint16(i) 1912 <-c // zBlank 1913 l = <-c // zString 1914 rr.Locator32 = net.ParseIP(l.token) 1915 if rr.Locator32 == nil || l.err { 1916 return nil, &ParseError{f, "bad L32 Locator", l}, "" 1917 } 1918 return rr, nil, "" 1919} 1920 1921func setLP(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { 1922 rr := new(LP) 1923 rr.Hdr = h 1924 1925 l := <-c 1926 if l.length == 0 { // dynamic update rr. 1927 return rr, nil, "" 1928 } 1929 1930 i, e := strconv.ParseUint(l.token, 10, 16) 1931 if e != nil || l.err { 1932 return nil, &ParseError{f, "bad LP Preference", l}, "" 1933 } 1934 rr.Preference = uint16(i) 1935 1936 <-c // zBlank 1937 l = <-c // zString 1938 rr.Fqdn = l.token 1939 name, nameOk := toAbsoluteName(l.token, o) 1940 if l.err || !nameOk { 1941 return nil, &ParseError{f, "bad LP Fqdn", l}, "" 1942 } 1943 rr.Fqdn = name 1944 1945 return rr, nil, "" 1946} 1947 1948func setL64(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { 1949 rr := new(L64) 1950 rr.Hdr = h 1951 1952 l := <-c 1953 if l.length == 0 { // dynamic update rr. 1954 return rr, nil, "" 1955 } 1956 1957 i, e := strconv.ParseUint(l.token, 10, 16) 1958 if e != nil || l.err { 1959 return nil, &ParseError{f, "bad L64 Preference", l}, "" 1960 } 1961 rr.Preference = uint16(i) 1962 <-c // zBlank 1963 l = <-c // zString 1964 u, err := stringToNodeID(l) 1965 if err != nil || l.err { 1966 return nil, err, "" 1967 } 1968 rr.Locator64 = u 1969 return rr, nil, "" 1970} 1971 1972func setUID(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { 1973 rr := new(UID) 1974 rr.Hdr = h 1975 1976 l := <-c 1977 if l.length == 0 { // dynamic update rr. 1978 return rr, nil, "" 1979 } 1980 1981 i, e := strconv.ParseUint(l.token, 10, 32) 1982 if e != nil || l.err { 1983 return nil, &ParseError{f, "bad UID Uid", l}, "" 1984 } 1985 rr.Uid = uint32(i) 1986 return rr, nil, "" 1987} 1988 1989func setGID(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { 1990 rr := new(GID) 1991 rr.Hdr = h 1992 1993 l := <-c 1994 if l.length == 0 { // dynamic update rr. 1995 return rr, nil, "" 1996 } 1997 1998 i, e := strconv.ParseUint(l.token, 10, 32) 1999 if e != nil || l.err { 2000 return nil, &ParseError{f, "bad GID Gid", l}, "" 2001 } 2002 rr.Gid = uint32(i) 2003 return rr, nil, "" 2004} 2005 2006func setUINFO(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { 2007 rr := new(UINFO) 2008 rr.Hdr = h 2009 2010 s, e, c1 := endingToTxtSlice(c, "bad UINFO Uinfo", f) 2011 if e != nil { 2012 return nil, e, c1 2013 } 2014 if ln := len(s); ln == 0 { 2015 return rr, nil, c1 2016 } 2017 rr.Uinfo = s[0] // silently discard anything after the first character-string 2018 return rr, nil, c1 2019} 2020 2021func setPX(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { 2022 rr := new(PX) 2023 rr.Hdr = h 2024 2025 l := <-c 2026 if l.length == 0 { // dynamic update rr. 2027 return rr, nil, "" 2028 } 2029 2030 i, e := strconv.ParseUint(l.token, 10, 16) 2031 if e != nil || l.err { 2032 return nil, &ParseError{f, "bad PX Preference", l}, "" 2033 } 2034 rr.Preference = uint16(i) 2035 2036 <-c // zBlank 2037 l = <-c // zString 2038 rr.Map822 = l.token 2039 map822, map822Ok := toAbsoluteName(l.token, o) 2040 if l.err || !map822Ok { 2041 return nil, &ParseError{f, "bad PX Map822", l}, "" 2042 } 2043 rr.Map822 = map822 2044 2045 <-c // zBlank 2046 l = <-c // zString 2047 rr.Mapx400 = l.token 2048 mapx400, mapx400Ok := toAbsoluteName(l.token, o) 2049 if l.err || !mapx400Ok { 2050 return nil, &ParseError{f, "bad PX Mapx400", l}, "" 2051 } 2052 rr.Mapx400 = mapx400 2053 2054 return rr, nil, "" 2055} 2056 2057func setCAA(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { 2058 rr := new(CAA) 2059 rr.Hdr = h 2060 2061 l := <-c 2062 if l.length == 0 { // dynamic update rr. 2063 return rr, nil, l.comment 2064 } 2065 2066 i, err := strconv.ParseUint(l.token, 10, 8) 2067 if err != nil || l.err { 2068 return nil, &ParseError{f, "bad CAA Flag", l}, "" 2069 } 2070 rr.Flag = uint8(i) 2071 2072 <-c // zBlank 2073 l = <-c // zString 2074 if l.value != zString { 2075 return nil, &ParseError{f, "bad CAA Tag", l}, "" 2076 } 2077 rr.Tag = l.token 2078 2079 <-c // zBlank 2080 s, e, c1 := endingToTxtSlice(c, "bad CAA Value", f) 2081 if e != nil { 2082 return nil, e, "" 2083 } 2084 if len(s) != 1 { 2085 return nil, &ParseError{f, "bad CAA Value", l}, "" 2086 } 2087 rr.Value = s[0] 2088 return rr, nil, c1 2089} 2090 2091func setTKEY(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { 2092 rr := new(TKEY) 2093 rr.Hdr = h 2094 2095 l := <-c 2096 2097 // Algorithm 2098 if l.value != zString { 2099 return nil, &ParseError{f, "bad TKEY algorithm", l}, "" 2100 } 2101 rr.Algorithm = l.token 2102 <-c // zBlank 2103 2104 // Get the key length and key values 2105 l = <-c 2106 i, err := strconv.ParseUint(l.token, 10, 8) 2107 if err != nil || l.err { 2108 return nil, &ParseError{f, "bad TKEY key length", l}, "" 2109 } 2110 rr.KeySize = uint16(i) 2111 <-c // zBlank 2112 l = <-c 2113 if l.value != zString { 2114 return nil, &ParseError{f, "bad TKEY key", l}, "" 2115 } 2116 rr.Key = l.token 2117 <-c // zBlank 2118 2119 // Get the otherdata length and string data 2120 l = <-c 2121 i, err = strconv.ParseUint(l.token, 10, 8) 2122 if err != nil || l.err { 2123 return nil, &ParseError{f, "bad TKEY otherdata length", l}, "" 2124 } 2125 rr.OtherLen = uint16(i) 2126 <-c // zBlank 2127 l = <-c 2128 if l.value != zString { 2129 return nil, &ParseError{f, "bad TKEY otherday", l}, "" 2130 } 2131 rr.OtherData = l.token 2132 2133 return rr, nil, "" 2134} 2135 2136var typeToparserFunc = map[uint16]parserFunc{ 2137 TypeAAAA: {setAAAA, false}, 2138 TypeAFSDB: {setAFSDB, false}, 2139 TypeA: {setA, false}, 2140 TypeCAA: {setCAA, true}, 2141 TypeCDS: {setCDS, true}, 2142 TypeCDNSKEY: {setCDNSKEY, true}, 2143 TypeCERT: {setCERT, true}, 2144 TypeCNAME: {setCNAME, false}, 2145 TypeCSYNC: {setCSYNC, true}, 2146 TypeDHCID: {setDHCID, true}, 2147 TypeDLV: {setDLV, true}, 2148 TypeDNAME: {setDNAME, false}, 2149 TypeKEY: {setKEY, true}, 2150 TypeDNSKEY: {setDNSKEY, true}, 2151 TypeDS: {setDS, true}, 2152 TypeEID: {setEID, true}, 2153 TypeEUI48: {setEUI48, false}, 2154 TypeEUI64: {setEUI64, false}, 2155 TypeGID: {setGID, false}, 2156 TypeGPOS: {setGPOS, false}, 2157 TypeHINFO: {setHINFO, true}, 2158 TypeHIP: {setHIP, true}, 2159 TypeKX: {setKX, false}, 2160 TypeL32: {setL32, false}, 2161 TypeL64: {setL64, false}, 2162 TypeLOC: {setLOC, true}, 2163 TypeLP: {setLP, false}, 2164 TypeMB: {setMB, false}, 2165 TypeMD: {setMD, false}, 2166 TypeMF: {setMF, false}, 2167 TypeMG: {setMG, false}, 2168 TypeMINFO: {setMINFO, false}, 2169 TypeMR: {setMR, false}, 2170 TypeMX: {setMX, false}, 2171 TypeNAPTR: {setNAPTR, false}, 2172 TypeNID: {setNID, false}, 2173 TypeNIMLOC: {setNIMLOC, true}, 2174 TypeNINFO: {setNINFO, true}, 2175 TypeNSAPPTR: {setNSAPPTR, false}, 2176 TypeNSEC3PARAM: {setNSEC3PARAM, false}, 2177 TypeNSEC3: {setNSEC3, true}, 2178 TypeNSEC: {setNSEC, true}, 2179 TypeNS: {setNS, false}, 2180 TypeOPENPGPKEY: {setOPENPGPKEY, true}, 2181 TypePTR: {setPTR, false}, 2182 TypePX: {setPX, false}, 2183 TypeSIG: {setSIG, true}, 2184 TypeRKEY: {setRKEY, true}, 2185 TypeRP: {setRP, false}, 2186 TypeRRSIG: {setRRSIG, true}, 2187 TypeRT: {setRT, false}, 2188 TypeSMIMEA: {setSMIMEA, true}, 2189 TypeSOA: {setSOA, false}, 2190 TypeSPF: {setSPF, true}, 2191 TypeAVC: {setAVC, true}, 2192 TypeSRV: {setSRV, false}, 2193 TypeSSHFP: {setSSHFP, true}, 2194 TypeTALINK: {setTALINK, false}, 2195 TypeTA: {setTA, true}, 2196 TypeTLSA: {setTLSA, true}, 2197 TypeTXT: {setTXT, true}, 2198 TypeUID: {setUID, false}, 2199 TypeUINFO: {setUINFO, true}, 2200 TypeURI: {setURI, true}, 2201 TypeX25: {setX25, false}, 2202 TypeTKEY: {setTKEY, true}, 2203} 2204