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