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