1package dns 2 3import ( 4 "encoding/base64" 5 "net" 6 "strconv" 7 "strings" 8) 9 10// A remainder of the rdata with embedded spaces, return the parsed string (sans the spaces) 11// or an error 12func endingToString(c *zlexer, errstr string) (string, *ParseError) { 13 var s string 14 l, _ := c.Next() // zString 15 for l.value != zNewline && l.value != zEOF { 16 if l.err { 17 return s, &ParseError{"", errstr, l} 18 } 19 switch l.value { 20 case zString: 21 s += l.token 22 case zBlank: // Ok 23 default: 24 return "", &ParseError{"", errstr, l} 25 } 26 l, _ = c.Next() 27 } 28 29 return s, nil 30} 31 32// A remainder of the rdata with embedded spaces, split on unquoted whitespace 33// and return the parsed string slice or an error 34func endingToTxtSlice(c *zlexer, errstr string) ([]string, *ParseError) { 35 // Get the remaining data until we see a zNewline 36 l, _ := c.Next() 37 if l.err { 38 return nil, &ParseError{"", errstr, l} 39 } 40 41 // Build the slice 42 s := make([]string, 0) 43 quote := false 44 empty := false 45 for l.value != zNewline && l.value != zEOF { 46 if l.err { 47 return nil, &ParseError{"", errstr, l} 48 } 49 switch l.value { 50 case zString: 51 empty = false 52 if len(l.token) > 255 { 53 // split up tokens that are larger than 255 into 255-chunks 54 sx := []string{} 55 p, i := 0, 255 56 for { 57 if i <= len(l.token) { 58 sx = append(sx, l.token[p:i]) 59 } else { 60 sx = append(sx, l.token[p:]) 61 break 62 63 } 64 p, i = p+255, i+255 65 } 66 s = append(s, sx...) 67 break 68 } 69 70 s = append(s, l.token) 71 case zBlank: 72 if quote { 73 // zBlank can only be seen in between txt parts. 74 return nil, &ParseError{"", errstr, l} 75 } 76 case zQuote: 77 if empty && quote { 78 s = append(s, "") 79 } 80 quote = !quote 81 empty = true 82 default: 83 return nil, &ParseError{"", errstr, l} 84 } 85 l, _ = c.Next() 86 } 87 88 if quote { 89 return nil, &ParseError{"", errstr, l} 90 } 91 92 return s, nil 93} 94 95func (rr *A) parse(c *zlexer, o string) *ParseError { 96 l, _ := c.Next() 97 rr.A = net.ParseIP(l.token) 98 // IPv4 addresses cannot include ":". 99 // We do this rather than use net.IP's To4() because 100 // To4() treats IPv4-mapped IPv6 addresses as being 101 // IPv4. 102 isIPv4 := !strings.Contains(l.token, ":") 103 if rr.A == nil || !isIPv4 || l.err { 104 return &ParseError{"", "bad A A", l} 105 } 106 return slurpRemainder(c) 107} 108 109func (rr *AAAA) parse(c *zlexer, o string) *ParseError { 110 l, _ := c.Next() 111 rr.AAAA = net.ParseIP(l.token) 112 // IPv6 addresses must include ":", and IPv4 113 // addresses cannot include ":". 114 isIPv6 := strings.Contains(l.token, ":") 115 if rr.AAAA == nil || !isIPv6 || l.err { 116 return &ParseError{"", "bad AAAA AAAA", l} 117 } 118 return slurpRemainder(c) 119} 120 121func (rr *NS) parse(c *zlexer, o string) *ParseError { 122 l, _ := c.Next() 123 name, nameOk := toAbsoluteName(l.token, o) 124 if l.err || !nameOk { 125 return &ParseError{"", "bad NS Ns", l} 126 } 127 rr.Ns = name 128 return slurpRemainder(c) 129} 130 131func (rr *PTR) parse(c *zlexer, o string) *ParseError { 132 l, _ := c.Next() 133 name, nameOk := toAbsoluteName(l.token, o) 134 if l.err || !nameOk { 135 return &ParseError{"", "bad PTR Ptr", l} 136 } 137 rr.Ptr = name 138 return slurpRemainder(c) 139} 140 141func (rr *NSAPPTR) parse(c *zlexer, o string) *ParseError { 142 l, _ := c.Next() 143 name, nameOk := toAbsoluteName(l.token, o) 144 if l.err || !nameOk { 145 return &ParseError{"", "bad NSAP-PTR Ptr", l} 146 } 147 rr.Ptr = name 148 return slurpRemainder(c) 149} 150 151func (rr *RP) parse(c *zlexer, o string) *ParseError { 152 l, _ := c.Next() 153 mbox, mboxOk := toAbsoluteName(l.token, o) 154 if l.err || !mboxOk { 155 return &ParseError{"", "bad RP Mbox", l} 156 } 157 rr.Mbox = mbox 158 159 c.Next() // zBlank 160 l, _ = c.Next() 161 rr.Txt = l.token 162 163 txt, txtOk := toAbsoluteName(l.token, o) 164 if l.err || !txtOk { 165 return &ParseError{"", "bad RP Txt", l} 166 } 167 rr.Txt = txt 168 169 return slurpRemainder(c) 170} 171 172func (rr *MR) parse(c *zlexer, o string) *ParseError { 173 l, _ := c.Next() 174 name, nameOk := toAbsoluteName(l.token, o) 175 if l.err || !nameOk { 176 return &ParseError{"", "bad MR Mr", l} 177 } 178 rr.Mr = name 179 return slurpRemainder(c) 180} 181 182func (rr *MB) parse(c *zlexer, o string) *ParseError { 183 l, _ := c.Next() 184 name, nameOk := toAbsoluteName(l.token, o) 185 if l.err || !nameOk { 186 return &ParseError{"", "bad MB Mb", l} 187 } 188 rr.Mb = name 189 return slurpRemainder(c) 190} 191 192func (rr *MG) parse(c *zlexer, o string) *ParseError { 193 l, _ := c.Next() 194 name, nameOk := toAbsoluteName(l.token, o) 195 if l.err || !nameOk { 196 return &ParseError{"", "bad MG Mg", l} 197 } 198 rr.Mg = name 199 return slurpRemainder(c) 200} 201 202func (rr *HINFO) parse(c *zlexer, o string) *ParseError { 203 chunks, e := endingToTxtSlice(c, "bad HINFO Fields") 204 if e != nil { 205 return e 206 } 207 208 if ln := len(chunks); ln == 0 { 209 return nil 210 } else if ln == 1 { 211 // Can we split it? 212 if out := strings.Fields(chunks[0]); len(out) > 1 { 213 chunks = out 214 } else { 215 chunks = append(chunks, "") 216 } 217 } 218 219 rr.Cpu = chunks[0] 220 rr.Os = strings.Join(chunks[1:], " ") 221 222 return nil 223} 224 225func (rr *MINFO) parse(c *zlexer, o string) *ParseError { 226 l, _ := c.Next() 227 rmail, rmailOk := toAbsoluteName(l.token, o) 228 if l.err || !rmailOk { 229 return &ParseError{"", "bad MINFO Rmail", l} 230 } 231 rr.Rmail = rmail 232 233 c.Next() // zBlank 234 l, _ = c.Next() 235 rr.Email = l.token 236 237 email, emailOk := toAbsoluteName(l.token, o) 238 if l.err || !emailOk { 239 return &ParseError{"", "bad MINFO Email", l} 240 } 241 rr.Email = email 242 243 return slurpRemainder(c) 244} 245 246func (rr *MF) parse(c *zlexer, o string) *ParseError { 247 l, _ := c.Next() 248 name, nameOk := toAbsoluteName(l.token, o) 249 if l.err || !nameOk { 250 return &ParseError{"", "bad MF Mf", l} 251 } 252 rr.Mf = name 253 return slurpRemainder(c) 254} 255 256func (rr *MD) parse(c *zlexer, o string) *ParseError { 257 l, _ := c.Next() 258 name, nameOk := toAbsoluteName(l.token, o) 259 if l.err || !nameOk { 260 return &ParseError{"", "bad MD Md", l} 261 } 262 rr.Md = name 263 return slurpRemainder(c) 264} 265 266func (rr *MX) parse(c *zlexer, o string) *ParseError { 267 l, _ := c.Next() 268 i, e := strconv.ParseUint(l.token, 10, 16) 269 if e != nil || l.err { 270 return &ParseError{"", "bad MX Pref", l} 271 } 272 rr.Preference = uint16(i) 273 274 c.Next() // zBlank 275 l, _ = c.Next() // zString 276 rr.Mx = l.token 277 278 name, nameOk := toAbsoluteName(l.token, o) 279 if l.err || !nameOk { 280 return &ParseError{"", "bad MX Mx", l} 281 } 282 rr.Mx = name 283 284 return slurpRemainder(c) 285} 286 287func (rr *RT) parse(c *zlexer, o string) *ParseError { 288 l, _ := c.Next() 289 i, e := strconv.ParseUint(l.token, 10, 16) 290 if e != nil { 291 return &ParseError{"", "bad RT Preference", l} 292 } 293 rr.Preference = uint16(i) 294 295 c.Next() // zBlank 296 l, _ = c.Next() // zString 297 rr.Host = l.token 298 299 name, nameOk := toAbsoluteName(l.token, o) 300 if l.err || !nameOk { 301 return &ParseError{"", "bad RT Host", l} 302 } 303 rr.Host = name 304 305 return slurpRemainder(c) 306} 307 308func (rr *AFSDB) parse(c *zlexer, o string) *ParseError { 309 l, _ := c.Next() 310 i, e := strconv.ParseUint(l.token, 10, 16) 311 if e != nil || l.err { 312 return &ParseError{"", "bad AFSDB Subtype", l} 313 } 314 rr.Subtype = uint16(i) 315 316 c.Next() // zBlank 317 l, _ = c.Next() // zString 318 rr.Hostname = l.token 319 320 name, nameOk := toAbsoluteName(l.token, o) 321 if l.err || !nameOk { 322 return &ParseError{"", "bad AFSDB Hostname", l} 323 } 324 rr.Hostname = name 325 return slurpRemainder(c) 326} 327 328func (rr *X25) parse(c *zlexer, o string) *ParseError { 329 l, _ := c.Next() 330 if l.err { 331 return &ParseError{"", "bad X25 PSDNAddress", l} 332 } 333 rr.PSDNAddress = l.token 334 return slurpRemainder(c) 335} 336 337func (rr *KX) parse(c *zlexer, o string) *ParseError { 338 l, _ := c.Next() 339 i, e := strconv.ParseUint(l.token, 10, 16) 340 if e != nil || l.err { 341 return &ParseError{"", "bad KX Pref", l} 342 } 343 rr.Preference = uint16(i) 344 345 c.Next() // zBlank 346 l, _ = c.Next() // zString 347 rr.Exchanger = l.token 348 349 name, nameOk := toAbsoluteName(l.token, o) 350 if l.err || !nameOk { 351 return &ParseError{"", "bad KX Exchanger", l} 352 } 353 rr.Exchanger = name 354 return slurpRemainder(c) 355} 356 357func (rr *CNAME) parse(c *zlexer, o string) *ParseError { 358 l, _ := c.Next() 359 name, nameOk := toAbsoluteName(l.token, o) 360 if l.err || !nameOk { 361 return &ParseError{"", "bad CNAME Target", l} 362 } 363 rr.Target = name 364 return slurpRemainder(c) 365} 366 367func (rr *DNAME) parse(c *zlexer, o string) *ParseError { 368 l, _ := c.Next() 369 name, nameOk := toAbsoluteName(l.token, o) 370 if l.err || !nameOk { 371 return &ParseError{"", "bad DNAME Target", l} 372 } 373 rr.Target = name 374 return slurpRemainder(c) 375} 376 377func (rr *SOA) parse(c *zlexer, o string) *ParseError { 378 l, _ := c.Next() 379 ns, nsOk := toAbsoluteName(l.token, o) 380 if l.err || !nsOk { 381 return &ParseError{"", "bad SOA Ns", l} 382 } 383 rr.Ns = ns 384 385 c.Next() // zBlank 386 l, _ = c.Next() 387 rr.Mbox = l.token 388 389 mbox, mboxOk := toAbsoluteName(l.token, o) 390 if l.err || !mboxOk { 391 return &ParseError{"", "bad SOA Mbox", l} 392 } 393 rr.Mbox = mbox 394 395 c.Next() // zBlank 396 397 var ( 398 v uint32 399 ok bool 400 ) 401 for i := 0; i < 5; i++ { 402 l, _ = c.Next() 403 if l.err { 404 return &ParseError{"", "bad SOA zone parameter", l} 405 } 406 if j, e := strconv.ParseUint(l.token, 10, 32); e != nil { 407 if i == 0 { 408 // Serial must be a number 409 return &ParseError{"", "bad SOA zone parameter", l} 410 } 411 // We allow other fields to be unitful duration strings 412 if v, ok = stringToTTL(l.token); !ok { 413 return &ParseError{"", "bad SOA zone parameter", l} 414 415 } 416 } else { 417 v = uint32(j) 418 } 419 switch i { 420 case 0: 421 rr.Serial = v 422 c.Next() // zBlank 423 case 1: 424 rr.Refresh = v 425 c.Next() // zBlank 426 case 2: 427 rr.Retry = v 428 c.Next() // zBlank 429 case 3: 430 rr.Expire = v 431 c.Next() // zBlank 432 case 4: 433 rr.Minttl = v 434 } 435 } 436 return slurpRemainder(c) 437} 438 439func (rr *SRV) parse(c *zlexer, o string) *ParseError { 440 l, _ := c.Next() 441 i, e := strconv.ParseUint(l.token, 10, 16) 442 if e != nil || l.err { 443 return &ParseError{"", "bad SRV Priority", l} 444 } 445 rr.Priority = uint16(i) 446 447 c.Next() // zBlank 448 l, _ = c.Next() // zString 449 i, e = strconv.ParseUint(l.token, 10, 16) 450 if e != nil || l.err { 451 return &ParseError{"", "bad SRV Weight", l} 452 } 453 rr.Weight = uint16(i) 454 455 c.Next() // zBlank 456 l, _ = c.Next() // zString 457 i, e = strconv.ParseUint(l.token, 10, 16) 458 if e != nil || l.err { 459 return &ParseError{"", "bad SRV Port", l} 460 } 461 rr.Port = uint16(i) 462 463 c.Next() // zBlank 464 l, _ = c.Next() // zString 465 rr.Target = l.token 466 467 name, nameOk := toAbsoluteName(l.token, o) 468 if l.err || !nameOk { 469 return &ParseError{"", "bad SRV Target", l} 470 } 471 rr.Target = name 472 return slurpRemainder(c) 473} 474 475func (rr *NAPTR) parse(c *zlexer, o string) *ParseError { 476 l, _ := c.Next() 477 i, e := strconv.ParseUint(l.token, 10, 16) 478 if e != nil || l.err { 479 return &ParseError{"", "bad NAPTR Order", l} 480 } 481 rr.Order = uint16(i) 482 483 c.Next() // zBlank 484 l, _ = c.Next() // zString 485 i, e = strconv.ParseUint(l.token, 10, 16) 486 if e != nil || l.err { 487 return &ParseError{"", "bad NAPTR Preference", l} 488 } 489 rr.Preference = uint16(i) 490 491 // Flags 492 c.Next() // zBlank 493 l, _ = c.Next() // _QUOTE 494 if l.value != zQuote { 495 return &ParseError{"", "bad NAPTR Flags", l} 496 } 497 l, _ = c.Next() // Either String or Quote 498 if l.value == zString { 499 rr.Flags = l.token 500 l, _ = c.Next() // _QUOTE 501 if l.value != zQuote { 502 return &ParseError{"", "bad NAPTR Flags", l} 503 } 504 } else if l.value == zQuote { 505 rr.Flags = "" 506 } else { 507 return &ParseError{"", "bad NAPTR Flags", l} 508 } 509 510 // Service 511 c.Next() // zBlank 512 l, _ = c.Next() // _QUOTE 513 if l.value != zQuote { 514 return &ParseError{"", "bad NAPTR Service", l} 515 } 516 l, _ = c.Next() // Either String or Quote 517 if l.value == zString { 518 rr.Service = l.token 519 l, _ = c.Next() // _QUOTE 520 if l.value != zQuote { 521 return &ParseError{"", "bad NAPTR Service", l} 522 } 523 } else if l.value == zQuote { 524 rr.Service = "" 525 } else { 526 return &ParseError{"", "bad NAPTR Service", l} 527 } 528 529 // Regexp 530 c.Next() // zBlank 531 l, _ = c.Next() // _QUOTE 532 if l.value != zQuote { 533 return &ParseError{"", "bad NAPTR Regexp", l} 534 } 535 l, _ = c.Next() // Either String or Quote 536 if l.value == zString { 537 rr.Regexp = l.token 538 l, _ = c.Next() // _QUOTE 539 if l.value != zQuote { 540 return &ParseError{"", "bad NAPTR Regexp", l} 541 } 542 } else if l.value == zQuote { 543 rr.Regexp = "" 544 } else { 545 return &ParseError{"", "bad NAPTR Regexp", l} 546 } 547 548 // After quote no space?? 549 c.Next() // zBlank 550 l, _ = c.Next() // zString 551 rr.Replacement = l.token 552 553 name, nameOk := toAbsoluteName(l.token, o) 554 if l.err || !nameOk { 555 return &ParseError{"", "bad NAPTR Replacement", l} 556 } 557 rr.Replacement = name 558 return slurpRemainder(c) 559} 560 561func (rr *TALINK) parse(c *zlexer, o string) *ParseError { 562 l, _ := c.Next() 563 previousName, previousNameOk := toAbsoluteName(l.token, o) 564 if l.err || !previousNameOk { 565 return &ParseError{"", "bad TALINK PreviousName", l} 566 } 567 rr.PreviousName = previousName 568 569 c.Next() // zBlank 570 l, _ = c.Next() 571 rr.NextName = l.token 572 573 nextName, nextNameOk := toAbsoluteName(l.token, o) 574 if l.err || !nextNameOk { 575 return &ParseError{"", "bad TALINK NextName", l} 576 } 577 rr.NextName = nextName 578 579 return slurpRemainder(c) 580} 581 582func (rr *LOC) parse(c *zlexer, o string) *ParseError { 583 // Non zero defaults for LOC record, see RFC 1876, Section 3. 584 rr.HorizPre = 165 // 10000 585 rr.VertPre = 162 // 10 586 rr.Size = 18 // 1 587 ok := false 588 589 // North 590 l, _ := c.Next() 591 i, e := strconv.ParseUint(l.token, 10, 32) 592 if e != nil || l.err { 593 return &ParseError{"", "bad LOC Latitude", l} 594 } 595 rr.Latitude = 1000 * 60 * 60 * uint32(i) 596 597 c.Next() // zBlank 598 // Either number, 'N' or 'S' 599 l, _ = c.Next() 600 if rr.Latitude, ok = locCheckNorth(l.token, rr.Latitude); ok { 601 goto East 602 } 603 i, e = strconv.ParseUint(l.token, 10, 32) 604 if e != nil || l.err { 605 return &ParseError{"", "bad LOC Latitude minutes", l} 606 } 607 rr.Latitude += 1000 * 60 * uint32(i) 608 609 c.Next() // zBlank 610 l, _ = c.Next() 611 if i, e := strconv.ParseFloat(l.token, 32); e != nil || l.err { 612 return &ParseError{"", "bad LOC Latitude seconds", l} 613 } else { 614 rr.Latitude += uint32(1000 * i) 615 } 616 c.Next() // zBlank 617 // Either number, 'N' or 'S' 618 l, _ = c.Next() 619 if rr.Latitude, ok = locCheckNorth(l.token, rr.Latitude); ok { 620 goto East 621 } 622 // If still alive, flag an error 623 return &ParseError{"", "bad LOC Latitude North/South", l} 624 625East: 626 // East 627 c.Next() // zBlank 628 l, _ = c.Next() 629 if i, e := strconv.ParseUint(l.token, 10, 32); e != nil || l.err { 630 return &ParseError{"", "bad LOC Longitude", l} 631 } else { 632 rr.Longitude = 1000 * 60 * 60 * uint32(i) 633 } 634 c.Next() // zBlank 635 // Either number, 'E' or 'W' 636 l, _ = c.Next() 637 if rr.Longitude, ok = locCheckEast(l.token, rr.Longitude); ok { 638 goto Altitude 639 } 640 if i, e := strconv.ParseUint(l.token, 10, 32); e != nil || l.err { 641 return &ParseError{"", "bad LOC Longitude minutes", l} 642 } else { 643 rr.Longitude += 1000 * 60 * uint32(i) 644 } 645 c.Next() // zBlank 646 l, _ = c.Next() 647 if i, e := strconv.ParseFloat(l.token, 32); e != nil || l.err { 648 return &ParseError{"", "bad LOC Longitude seconds", l} 649 } else { 650 rr.Longitude += uint32(1000 * i) 651 } 652 c.Next() // zBlank 653 // Either number, 'E' or 'W' 654 l, _ = c.Next() 655 if rr.Longitude, ok = locCheckEast(l.token, rr.Longitude); ok { 656 goto Altitude 657 } 658 // If still alive, flag an error 659 return &ParseError{"", "bad LOC Longitude East/West", l} 660 661Altitude: 662 c.Next() // zBlank 663 l, _ = c.Next() 664 if len(l.token) == 0 || l.err { 665 return &ParseError{"", "bad LOC Altitude", l} 666 } 667 if l.token[len(l.token)-1] == 'M' || l.token[len(l.token)-1] == 'm' { 668 l.token = l.token[0 : len(l.token)-1] 669 } 670 if i, e := strconv.ParseFloat(l.token, 32); e != nil { 671 return &ParseError{"", "bad LOC Altitude", l} 672 } else { 673 rr.Altitude = uint32(i*100.0 + 10000000.0 + 0.5) 674 } 675 676 // And now optionally the other values 677 l, _ = c.Next() 678 count := 0 679 for l.value != zNewline && l.value != zEOF { 680 switch l.value { 681 case zString: 682 switch count { 683 case 0: // Size 684 e, m, ok := stringToCm(l.token) 685 if !ok { 686 return &ParseError{"", "bad LOC Size", l} 687 } 688 rr.Size = e&0x0f | m<<4&0xf0 689 case 1: // HorizPre 690 e, m, ok := stringToCm(l.token) 691 if !ok { 692 return &ParseError{"", "bad LOC HorizPre", l} 693 } 694 rr.HorizPre = e&0x0f | m<<4&0xf0 695 case 2: // VertPre 696 e, m, ok := stringToCm(l.token) 697 if !ok { 698 return &ParseError{"", "bad LOC VertPre", l} 699 } 700 rr.VertPre = e&0x0f | m<<4&0xf0 701 } 702 count++ 703 case zBlank: 704 // Ok 705 default: 706 return &ParseError{"", "bad LOC Size, HorizPre or VertPre", l} 707 } 708 l, _ = c.Next() 709 } 710 return nil 711} 712 713func (rr *HIP) parse(c *zlexer, o string) *ParseError { 714 // HitLength is not represented 715 l, _ := c.Next() 716 i, e := strconv.ParseUint(l.token, 10, 8) 717 if e != nil || l.err { 718 return &ParseError{"", "bad HIP PublicKeyAlgorithm", l} 719 } 720 rr.PublicKeyAlgorithm = uint8(i) 721 722 c.Next() // zBlank 723 l, _ = c.Next() // zString 724 if len(l.token) == 0 || l.err { 725 return &ParseError{"", "bad HIP Hit", l} 726 } 727 rr.Hit = l.token // This can not contain spaces, see RFC 5205 Section 6. 728 rr.HitLength = uint8(len(rr.Hit)) / 2 729 730 c.Next() // zBlank 731 l, _ = c.Next() // zString 732 if len(l.token) == 0 || l.err { 733 return &ParseError{"", "bad HIP PublicKey", l} 734 } 735 rr.PublicKey = l.token // This cannot contain spaces 736 rr.PublicKeyLength = uint16(base64.StdEncoding.DecodedLen(len(rr.PublicKey))) 737 738 // RendezvousServers (if any) 739 l, _ = c.Next() 740 var xs []string 741 for l.value != zNewline && l.value != zEOF { 742 switch l.value { 743 case zString: 744 name, nameOk := toAbsoluteName(l.token, o) 745 if l.err || !nameOk { 746 return &ParseError{"", "bad HIP RendezvousServers", l} 747 } 748 xs = append(xs, name) 749 case zBlank: 750 // Ok 751 default: 752 return &ParseError{"", "bad HIP RendezvousServers", l} 753 } 754 l, _ = c.Next() 755 } 756 757 rr.RendezvousServers = xs 758 return nil 759} 760 761func (rr *CERT) parse(c *zlexer, o string) *ParseError { 762 l, _ := c.Next() 763 if v, ok := StringToCertType[l.token]; ok { 764 rr.Type = v 765 } else if i, e := strconv.ParseUint(l.token, 10, 16); e != nil { 766 return &ParseError{"", "bad CERT Type", l} 767 } else { 768 rr.Type = uint16(i) 769 } 770 c.Next() // zBlank 771 l, _ = c.Next() // zString 772 i, e := strconv.ParseUint(l.token, 10, 16) 773 if e != nil || l.err { 774 return &ParseError{"", "bad CERT KeyTag", l} 775 } 776 rr.KeyTag = uint16(i) 777 c.Next() // zBlank 778 l, _ = c.Next() // zString 779 if v, ok := StringToAlgorithm[l.token]; ok { 780 rr.Algorithm = v 781 } else if i, e := strconv.ParseUint(l.token, 10, 8); e != nil { 782 return &ParseError{"", "bad CERT Algorithm", l} 783 } else { 784 rr.Algorithm = uint8(i) 785 } 786 s, e1 := endingToString(c, "bad CERT Certificate") 787 if e1 != nil { 788 return e1 789 } 790 rr.Certificate = s 791 return nil 792} 793 794func (rr *OPENPGPKEY) parse(c *zlexer, o string) *ParseError { 795 s, e := endingToString(c, "bad OPENPGPKEY PublicKey") 796 if e != nil { 797 return e 798 } 799 rr.PublicKey = s 800 return nil 801} 802 803func (rr *CSYNC) parse(c *zlexer, o string) *ParseError { 804 l, _ := c.Next() 805 j, e := strconv.ParseUint(l.token, 10, 32) 806 if e != nil { 807 // Serial must be a number 808 return &ParseError{"", "bad CSYNC serial", l} 809 } 810 rr.Serial = uint32(j) 811 812 c.Next() // zBlank 813 814 l, _ = c.Next() 815 j, e = strconv.ParseUint(l.token, 10, 16) 816 if e != nil { 817 // Serial must be a number 818 return &ParseError{"", "bad CSYNC flags", l} 819 } 820 rr.Flags = uint16(j) 821 822 rr.TypeBitMap = make([]uint16, 0) 823 var ( 824 k uint16 825 ok bool 826 ) 827 l, _ = c.Next() 828 for l.value != zNewline && l.value != zEOF { 829 switch l.value { 830 case zBlank: 831 // Ok 832 case zString: 833 tokenUpper := strings.ToUpper(l.token) 834 if k, ok = StringToType[tokenUpper]; !ok { 835 if k, ok = typeToInt(l.token); !ok { 836 return &ParseError{"", "bad CSYNC TypeBitMap", l} 837 } 838 } 839 rr.TypeBitMap = append(rr.TypeBitMap, k) 840 default: 841 return &ParseError{"", "bad CSYNC TypeBitMap", l} 842 } 843 l, _ = c.Next() 844 } 845 return nil 846} 847 848func (rr *SIG) parse(c *zlexer, o string) *ParseError { 849 return rr.RRSIG.parse(c, o) 850} 851 852func (rr *RRSIG) parse(c *zlexer, o string) *ParseError { 853 l, _ := c.Next() 854 tokenUpper := strings.ToUpper(l.token) 855 if t, ok := StringToType[tokenUpper]; !ok { 856 if strings.HasPrefix(tokenUpper, "TYPE") { 857 t, ok = typeToInt(l.token) 858 if !ok { 859 return &ParseError{"", "bad RRSIG Typecovered", l} 860 } 861 rr.TypeCovered = t 862 } else { 863 return &ParseError{"", "bad RRSIG Typecovered", l} 864 } 865 } else { 866 rr.TypeCovered = t 867 } 868 869 c.Next() // zBlank 870 l, _ = c.Next() 871 i, err := strconv.ParseUint(l.token, 10, 8) 872 if err != nil || l.err { 873 return &ParseError{"", "bad RRSIG Algorithm", l} 874 } 875 rr.Algorithm = uint8(i) 876 877 c.Next() // zBlank 878 l, _ = c.Next() 879 i, err = strconv.ParseUint(l.token, 10, 8) 880 if err != nil || l.err { 881 return &ParseError{"", "bad RRSIG Labels", l} 882 } 883 rr.Labels = uint8(i) 884 885 c.Next() // zBlank 886 l, _ = c.Next() 887 i, err = strconv.ParseUint(l.token, 10, 32) 888 if err != nil || l.err { 889 return &ParseError{"", "bad RRSIG OrigTtl", l} 890 } 891 rr.OrigTtl = uint32(i) 892 893 c.Next() // zBlank 894 l, _ = c.Next() 895 if i, err := StringToTime(l.token); err != nil { 896 // Try to see if all numeric and use it as epoch 897 if i, err := strconv.ParseInt(l.token, 10, 64); err == nil { 898 // TODO(miek): error out on > MAX_UINT32, same below 899 rr.Expiration = uint32(i) 900 } else { 901 return &ParseError{"", "bad RRSIG Expiration", l} 902 } 903 } else { 904 rr.Expiration = i 905 } 906 907 c.Next() // zBlank 908 l, _ = c.Next() 909 if i, err := StringToTime(l.token); err != nil { 910 if i, err := strconv.ParseInt(l.token, 10, 64); err == nil { 911 rr.Inception = uint32(i) 912 } else { 913 return &ParseError{"", "bad RRSIG Inception", l} 914 } 915 } else { 916 rr.Inception = i 917 } 918 919 c.Next() // zBlank 920 l, _ = c.Next() 921 i, err = strconv.ParseUint(l.token, 10, 16) 922 if err != nil || l.err { 923 return &ParseError{"", "bad RRSIG KeyTag", l} 924 } 925 rr.KeyTag = uint16(i) 926 927 c.Next() // zBlank 928 l, _ = c.Next() 929 rr.SignerName = l.token 930 name, nameOk := toAbsoluteName(l.token, o) 931 if l.err || !nameOk { 932 return &ParseError{"", "bad RRSIG SignerName", l} 933 } 934 rr.SignerName = name 935 936 s, e := endingToString(c, "bad RRSIG Signature") 937 if e != nil { 938 return e 939 } 940 rr.Signature = s 941 942 return nil 943} 944 945func (rr *NSEC) parse(c *zlexer, o string) *ParseError { 946 l, _ := c.Next() 947 name, nameOk := toAbsoluteName(l.token, o) 948 if l.err || !nameOk { 949 return &ParseError{"", "bad NSEC NextDomain", l} 950 } 951 rr.NextDomain = name 952 953 rr.TypeBitMap = make([]uint16, 0) 954 var ( 955 k uint16 956 ok bool 957 ) 958 l, _ = c.Next() 959 for l.value != zNewline && l.value != zEOF { 960 switch l.value { 961 case zBlank: 962 // Ok 963 case zString: 964 tokenUpper := strings.ToUpper(l.token) 965 if k, ok = StringToType[tokenUpper]; !ok { 966 if k, ok = typeToInt(l.token); !ok { 967 return &ParseError{"", "bad NSEC TypeBitMap", l} 968 } 969 } 970 rr.TypeBitMap = append(rr.TypeBitMap, k) 971 default: 972 return &ParseError{"", "bad NSEC TypeBitMap", l} 973 } 974 l, _ = c.Next() 975 } 976 return nil 977} 978 979func (rr *NSEC3) parse(c *zlexer, o string) *ParseError { 980 l, _ := c.Next() 981 i, e := strconv.ParseUint(l.token, 10, 8) 982 if e != nil || l.err { 983 return &ParseError{"", "bad NSEC3 Hash", l} 984 } 985 rr.Hash = uint8(i) 986 c.Next() // zBlank 987 l, _ = c.Next() 988 i, e = strconv.ParseUint(l.token, 10, 8) 989 if e != nil || l.err { 990 return &ParseError{"", "bad NSEC3 Flags", l} 991 } 992 rr.Flags = uint8(i) 993 c.Next() // zBlank 994 l, _ = c.Next() 995 i, e = strconv.ParseUint(l.token, 10, 16) 996 if e != nil || l.err { 997 return &ParseError{"", "bad NSEC3 Iterations", l} 998 } 999 rr.Iterations = uint16(i) 1000 c.Next() 1001 l, _ = c.Next() 1002 if len(l.token) == 0 || l.err { 1003 return &ParseError{"", "bad NSEC3 Salt", l} 1004 } 1005 if l.token != "-" { 1006 rr.SaltLength = uint8(len(l.token)) / 2 1007 rr.Salt = l.token 1008 } 1009 1010 c.Next() 1011 l, _ = c.Next() 1012 if len(l.token) == 0 || l.err { 1013 return &ParseError{"", "bad NSEC3 NextDomain", l} 1014 } 1015 rr.HashLength = 20 // Fix for NSEC3 (sha1 160 bits) 1016 rr.NextDomain = l.token 1017 1018 rr.TypeBitMap = make([]uint16, 0) 1019 var ( 1020 k uint16 1021 ok bool 1022 ) 1023 l, _ = c.Next() 1024 for l.value != zNewline && l.value != zEOF { 1025 switch l.value { 1026 case zBlank: 1027 // Ok 1028 case zString: 1029 tokenUpper := strings.ToUpper(l.token) 1030 if k, ok = StringToType[tokenUpper]; !ok { 1031 if k, ok = typeToInt(l.token); !ok { 1032 return &ParseError{"", "bad NSEC3 TypeBitMap", l} 1033 } 1034 } 1035 rr.TypeBitMap = append(rr.TypeBitMap, k) 1036 default: 1037 return &ParseError{"", "bad NSEC3 TypeBitMap", l} 1038 } 1039 l, _ = c.Next() 1040 } 1041 return nil 1042} 1043 1044func (rr *NSEC3PARAM) parse(c *zlexer, o string) *ParseError { 1045 l, _ := c.Next() 1046 i, e := strconv.ParseUint(l.token, 10, 8) 1047 if e != nil || l.err { 1048 return &ParseError{"", "bad NSEC3PARAM Hash", l} 1049 } 1050 rr.Hash = uint8(i) 1051 c.Next() // zBlank 1052 l, _ = c.Next() 1053 i, e = strconv.ParseUint(l.token, 10, 8) 1054 if e != nil || l.err { 1055 return &ParseError{"", "bad NSEC3PARAM Flags", l} 1056 } 1057 rr.Flags = uint8(i) 1058 c.Next() // zBlank 1059 l, _ = c.Next() 1060 i, e = strconv.ParseUint(l.token, 10, 16) 1061 if e != nil || l.err { 1062 return &ParseError{"", "bad NSEC3PARAM Iterations", l} 1063 } 1064 rr.Iterations = uint16(i) 1065 c.Next() 1066 l, _ = c.Next() 1067 if l.token != "-" { 1068 rr.SaltLength = uint8(len(l.token)) 1069 rr.Salt = l.token 1070 } 1071 return slurpRemainder(c) 1072} 1073 1074func (rr *EUI48) parse(c *zlexer, o string) *ParseError { 1075 l, _ := c.Next() 1076 if len(l.token) != 17 || l.err { 1077 return &ParseError{"", "bad EUI48 Address", l} 1078 } 1079 addr := make([]byte, 12) 1080 dash := 0 1081 for i := 0; i < 10; i += 2 { 1082 addr[i] = l.token[i+dash] 1083 addr[i+1] = l.token[i+1+dash] 1084 dash++ 1085 if l.token[i+1+dash] != '-' { 1086 return &ParseError{"", "bad EUI48 Address", l} 1087 } 1088 } 1089 addr[10] = l.token[15] 1090 addr[11] = l.token[16] 1091 1092 i, e := strconv.ParseUint(string(addr), 16, 48) 1093 if e != nil { 1094 return &ParseError{"", "bad EUI48 Address", l} 1095 } 1096 rr.Address = i 1097 return slurpRemainder(c) 1098} 1099 1100func (rr *EUI64) parse(c *zlexer, o string) *ParseError { 1101 l, _ := c.Next() 1102 if len(l.token) != 23 || l.err { 1103 return &ParseError{"", "bad EUI64 Address", l} 1104 } 1105 addr := make([]byte, 16) 1106 dash := 0 1107 for i := 0; i < 14; i += 2 { 1108 addr[i] = l.token[i+dash] 1109 addr[i+1] = l.token[i+1+dash] 1110 dash++ 1111 if l.token[i+1+dash] != '-' { 1112 return &ParseError{"", "bad EUI64 Address", l} 1113 } 1114 } 1115 addr[14] = l.token[21] 1116 addr[15] = l.token[22] 1117 1118 i, e := strconv.ParseUint(string(addr), 16, 64) 1119 if e != nil { 1120 return &ParseError{"", "bad EUI68 Address", l} 1121 } 1122 rr.Address = i 1123 return slurpRemainder(c) 1124} 1125 1126func (rr *SSHFP) parse(c *zlexer, o string) *ParseError { 1127 l, _ := c.Next() 1128 i, e := strconv.ParseUint(l.token, 10, 8) 1129 if e != nil || l.err { 1130 return &ParseError{"", "bad SSHFP Algorithm", l} 1131 } 1132 rr.Algorithm = uint8(i) 1133 c.Next() // zBlank 1134 l, _ = c.Next() 1135 i, e = strconv.ParseUint(l.token, 10, 8) 1136 if e != nil || l.err { 1137 return &ParseError{"", "bad SSHFP Type", l} 1138 } 1139 rr.Type = uint8(i) 1140 c.Next() // zBlank 1141 s, e1 := endingToString(c, "bad SSHFP Fingerprint") 1142 if e1 != nil { 1143 return e1 1144 } 1145 rr.FingerPrint = s 1146 return nil 1147} 1148 1149func (rr *DNSKEY) parseDNSKEY(c *zlexer, o, typ string) *ParseError { 1150 l, _ := c.Next() 1151 i, e := strconv.ParseUint(l.token, 10, 16) 1152 if e != nil || l.err { 1153 return &ParseError{"", "bad " + typ + " Flags", l} 1154 } 1155 rr.Flags = uint16(i) 1156 c.Next() // zBlank 1157 l, _ = c.Next() // zString 1158 i, e = strconv.ParseUint(l.token, 10, 8) 1159 if e != nil || l.err { 1160 return &ParseError{"", "bad " + typ + " Protocol", l} 1161 } 1162 rr.Protocol = uint8(i) 1163 c.Next() // zBlank 1164 l, _ = c.Next() // zString 1165 i, e = strconv.ParseUint(l.token, 10, 8) 1166 if e != nil || l.err { 1167 return &ParseError{"", "bad " + typ + " Algorithm", l} 1168 } 1169 rr.Algorithm = uint8(i) 1170 s, e1 := endingToString(c, "bad "+typ+" PublicKey") 1171 if e1 != nil { 1172 return e1 1173 } 1174 rr.PublicKey = s 1175 return nil 1176} 1177 1178func (rr *DNSKEY) parse(c *zlexer, o string) *ParseError { 1179 return rr.parseDNSKEY(c, o, "DNSKEY") 1180} 1181 1182func (rr *KEY) parse(c *zlexer, o string) *ParseError { 1183 return rr.parseDNSKEY(c, o, "KEY") 1184} 1185 1186func (rr *CDNSKEY) parse(c *zlexer, o string) *ParseError { 1187 return rr.parseDNSKEY(c, o, "CDNSKEY") 1188} 1189 1190func (rr *RKEY) parse(c *zlexer, o string) *ParseError { 1191 l, _ := c.Next() 1192 i, e := strconv.ParseUint(l.token, 10, 16) 1193 if e != nil || l.err { 1194 return &ParseError{"", "bad RKEY Flags", l} 1195 } 1196 rr.Flags = uint16(i) 1197 c.Next() // zBlank 1198 l, _ = c.Next() // zString 1199 i, e = strconv.ParseUint(l.token, 10, 8) 1200 if e != nil || l.err { 1201 return &ParseError{"", "bad RKEY Protocol", l} 1202 } 1203 rr.Protocol = uint8(i) 1204 c.Next() // zBlank 1205 l, _ = c.Next() // zString 1206 i, e = strconv.ParseUint(l.token, 10, 8) 1207 if e != nil || l.err { 1208 return &ParseError{"", "bad RKEY Algorithm", l} 1209 } 1210 rr.Algorithm = uint8(i) 1211 s, e1 := endingToString(c, "bad RKEY PublicKey") 1212 if e1 != nil { 1213 return e1 1214 } 1215 rr.PublicKey = s 1216 return nil 1217} 1218 1219func (rr *EID) parse(c *zlexer, o string) *ParseError { 1220 s, e := endingToString(c, "bad EID Endpoint") 1221 if e != nil { 1222 return e 1223 } 1224 rr.Endpoint = s 1225 return nil 1226} 1227 1228func (rr *NIMLOC) parse(c *zlexer, o string) *ParseError { 1229 s, e := endingToString(c, "bad NIMLOC Locator") 1230 if e != nil { 1231 return e 1232 } 1233 rr.Locator = s 1234 return nil 1235} 1236 1237func (rr *GPOS) parse(c *zlexer, o string) *ParseError { 1238 l, _ := c.Next() 1239 _, e := strconv.ParseFloat(l.token, 64) 1240 if e != nil || l.err { 1241 return &ParseError{"", "bad GPOS Longitude", l} 1242 } 1243 rr.Longitude = l.token 1244 c.Next() // zBlank 1245 l, _ = c.Next() 1246 _, e = strconv.ParseFloat(l.token, 64) 1247 if e != nil || l.err { 1248 return &ParseError{"", "bad GPOS Latitude", l} 1249 } 1250 rr.Latitude = l.token 1251 c.Next() // zBlank 1252 l, _ = c.Next() 1253 _, e = strconv.ParseFloat(l.token, 64) 1254 if e != nil || l.err { 1255 return &ParseError{"", "bad GPOS Altitude", l} 1256 } 1257 rr.Altitude = l.token 1258 return slurpRemainder(c) 1259} 1260 1261func (rr *DS) parseDS(c *zlexer, o, typ string) *ParseError { 1262 l, _ := c.Next() 1263 i, e := strconv.ParseUint(l.token, 10, 16) 1264 if e != nil || l.err { 1265 return &ParseError{"", "bad " + typ + " KeyTag", l} 1266 } 1267 rr.KeyTag = uint16(i) 1268 c.Next() // zBlank 1269 l, _ = c.Next() 1270 if i, e = strconv.ParseUint(l.token, 10, 8); e != nil { 1271 tokenUpper := strings.ToUpper(l.token) 1272 i, ok := StringToAlgorithm[tokenUpper] 1273 if !ok || l.err { 1274 return &ParseError{"", "bad " + typ + " Algorithm", l} 1275 } 1276 rr.Algorithm = i 1277 } else { 1278 rr.Algorithm = uint8(i) 1279 } 1280 c.Next() // zBlank 1281 l, _ = c.Next() 1282 i, e = strconv.ParseUint(l.token, 10, 8) 1283 if e != nil || l.err { 1284 return &ParseError{"", "bad " + typ + " DigestType", l} 1285 } 1286 rr.DigestType = uint8(i) 1287 s, e1 := endingToString(c, "bad "+typ+" Digest") 1288 if e1 != nil { 1289 return e1 1290 } 1291 rr.Digest = s 1292 return nil 1293} 1294 1295func (rr *DS) parse(c *zlexer, o string) *ParseError { 1296 return rr.parseDS(c, o, "DS") 1297} 1298 1299func (rr *DLV) parse(c *zlexer, o string) *ParseError { 1300 return rr.parseDS(c, o, "DLV") 1301} 1302 1303func (rr *CDS) parse(c *zlexer, o string) *ParseError { 1304 return rr.parseDS(c, o, "CDS") 1305} 1306 1307func (rr *TA) parse(c *zlexer, o string) *ParseError { 1308 l, _ := c.Next() 1309 i, e := strconv.ParseUint(l.token, 10, 16) 1310 if e != nil || l.err { 1311 return &ParseError{"", "bad TA KeyTag", l} 1312 } 1313 rr.KeyTag = uint16(i) 1314 c.Next() // zBlank 1315 l, _ = c.Next() 1316 if i, e := strconv.ParseUint(l.token, 10, 8); e != nil { 1317 tokenUpper := strings.ToUpper(l.token) 1318 i, ok := StringToAlgorithm[tokenUpper] 1319 if !ok || l.err { 1320 return &ParseError{"", "bad TA Algorithm", l} 1321 } 1322 rr.Algorithm = i 1323 } else { 1324 rr.Algorithm = uint8(i) 1325 } 1326 c.Next() // zBlank 1327 l, _ = c.Next() 1328 i, e = strconv.ParseUint(l.token, 10, 8) 1329 if e != nil || l.err { 1330 return &ParseError{"", "bad TA DigestType", l} 1331 } 1332 rr.DigestType = uint8(i) 1333 s, err := endingToString(c, "bad TA Digest") 1334 if err != nil { 1335 return err 1336 } 1337 rr.Digest = s 1338 return nil 1339} 1340 1341func (rr *TLSA) parse(c *zlexer, o string) *ParseError { 1342 l, _ := c.Next() 1343 i, e := strconv.ParseUint(l.token, 10, 8) 1344 if e != nil || l.err { 1345 return &ParseError{"", "bad TLSA Usage", l} 1346 } 1347 rr.Usage = uint8(i) 1348 c.Next() // zBlank 1349 l, _ = c.Next() 1350 i, e = strconv.ParseUint(l.token, 10, 8) 1351 if e != nil || l.err { 1352 return &ParseError{"", "bad TLSA Selector", l} 1353 } 1354 rr.Selector = uint8(i) 1355 c.Next() // zBlank 1356 l, _ = c.Next() 1357 i, e = strconv.ParseUint(l.token, 10, 8) 1358 if e != nil || l.err { 1359 return &ParseError{"", "bad TLSA MatchingType", l} 1360 } 1361 rr.MatchingType = uint8(i) 1362 // So this needs be e2 (i.e. different than e), because...??t 1363 s, e2 := endingToString(c, "bad TLSA Certificate") 1364 if e2 != nil { 1365 return e2 1366 } 1367 rr.Certificate = s 1368 return nil 1369} 1370 1371func (rr *SMIMEA) parse(c *zlexer, o string) *ParseError { 1372 l, _ := c.Next() 1373 i, e := strconv.ParseUint(l.token, 10, 8) 1374 if e != nil || l.err { 1375 return &ParseError{"", "bad SMIMEA Usage", l} 1376 } 1377 rr.Usage = uint8(i) 1378 c.Next() // zBlank 1379 l, _ = c.Next() 1380 i, e = strconv.ParseUint(l.token, 10, 8) 1381 if e != nil || l.err { 1382 return &ParseError{"", "bad SMIMEA Selector", l} 1383 } 1384 rr.Selector = uint8(i) 1385 c.Next() // zBlank 1386 l, _ = c.Next() 1387 i, e = strconv.ParseUint(l.token, 10, 8) 1388 if e != nil || l.err { 1389 return &ParseError{"", "bad SMIMEA MatchingType", l} 1390 } 1391 rr.MatchingType = uint8(i) 1392 // So this needs be e2 (i.e. different than e), because...??t 1393 s, e2 := endingToString(c, "bad SMIMEA Certificate") 1394 if e2 != nil { 1395 return e2 1396 } 1397 rr.Certificate = s 1398 return nil 1399} 1400 1401func (rr *RFC3597) parse(c *zlexer, o string) *ParseError { 1402 l, _ := c.Next() 1403 if l.token != "\\#" { 1404 return &ParseError{"", "bad RFC3597 Rdata", l} 1405 } 1406 1407 c.Next() // zBlank 1408 l, _ = c.Next() 1409 rdlength, e := strconv.Atoi(l.token) 1410 if e != nil || l.err { 1411 return &ParseError{"", "bad RFC3597 Rdata ", l} 1412 } 1413 1414 s, e1 := endingToString(c, "bad RFC3597 Rdata") 1415 if e1 != nil { 1416 return e1 1417 } 1418 if rdlength*2 != len(s) { 1419 return &ParseError{"", "bad RFC3597 Rdata", l} 1420 } 1421 rr.Rdata = s 1422 return nil 1423} 1424 1425func (rr *SPF) parse(c *zlexer, o string) *ParseError { 1426 s, e := endingToTxtSlice(c, "bad SPF Txt") 1427 if e != nil { 1428 return e 1429 } 1430 rr.Txt = s 1431 return nil 1432} 1433 1434func (rr *AVC) parse(c *zlexer, o string) *ParseError { 1435 s, e := endingToTxtSlice(c, "bad AVC Txt") 1436 if e != nil { 1437 return e 1438 } 1439 rr.Txt = s 1440 return nil 1441} 1442 1443func (rr *TXT) parse(c *zlexer, o string) *ParseError { 1444 // no zBlank reading here, because all this rdata is TXT 1445 s, e := endingToTxtSlice(c, "bad TXT Txt") 1446 if e != nil { 1447 return e 1448 } 1449 rr.Txt = s 1450 return nil 1451} 1452 1453// identical to setTXT 1454func (rr *NINFO) parse(c *zlexer, o string) *ParseError { 1455 s, e := endingToTxtSlice(c, "bad NINFO ZSData") 1456 if e != nil { 1457 return e 1458 } 1459 rr.ZSData = s 1460 return nil 1461} 1462 1463func (rr *URI) parse(c *zlexer, o string) *ParseError { 1464 l, _ := c.Next() 1465 i, e := strconv.ParseUint(l.token, 10, 16) 1466 if e != nil || l.err { 1467 return &ParseError{"", "bad URI Priority", l} 1468 } 1469 rr.Priority = uint16(i) 1470 c.Next() // zBlank 1471 l, _ = c.Next() 1472 i, e = strconv.ParseUint(l.token, 10, 16) 1473 if e != nil || l.err { 1474 return &ParseError{"", "bad URI Weight", l} 1475 } 1476 rr.Weight = uint16(i) 1477 1478 c.Next() // zBlank 1479 s, err := endingToTxtSlice(c, "bad URI Target") 1480 if err != nil { 1481 return err 1482 } 1483 if len(s) != 1 { 1484 return &ParseError{"", "bad URI Target", l} 1485 } 1486 rr.Target = s[0] 1487 return nil 1488} 1489 1490func (rr *DHCID) parse(c *zlexer, o string) *ParseError { 1491 // awesome record to parse! 1492 s, e := endingToString(c, "bad DHCID Digest") 1493 if e != nil { 1494 return e 1495 } 1496 rr.Digest = s 1497 return nil 1498} 1499 1500func (rr *NID) parse(c *zlexer, o string) *ParseError { 1501 l, _ := c.Next() 1502 i, e := strconv.ParseUint(l.token, 10, 16) 1503 if e != nil || l.err { 1504 return &ParseError{"", "bad NID Preference", l} 1505 } 1506 rr.Preference = uint16(i) 1507 c.Next() // zBlank 1508 l, _ = c.Next() // zString 1509 u, err := stringToNodeID(l) 1510 if err != nil || l.err { 1511 return err 1512 } 1513 rr.NodeID = u 1514 return slurpRemainder(c) 1515} 1516 1517func (rr *L32) parse(c *zlexer, o string) *ParseError { 1518 l, _ := c.Next() 1519 i, e := strconv.ParseUint(l.token, 10, 16) 1520 if e != nil || l.err { 1521 return &ParseError{"", "bad L32 Preference", l} 1522 } 1523 rr.Preference = uint16(i) 1524 c.Next() // zBlank 1525 l, _ = c.Next() // zString 1526 rr.Locator32 = net.ParseIP(l.token) 1527 if rr.Locator32 == nil || l.err { 1528 return &ParseError{"", "bad L32 Locator", l} 1529 } 1530 return slurpRemainder(c) 1531} 1532 1533func (rr *LP) parse(c *zlexer, o string) *ParseError { 1534 l, _ := c.Next() 1535 i, e := strconv.ParseUint(l.token, 10, 16) 1536 if e != nil || l.err { 1537 return &ParseError{"", "bad LP Preference", l} 1538 } 1539 rr.Preference = uint16(i) 1540 1541 c.Next() // zBlank 1542 l, _ = c.Next() // zString 1543 rr.Fqdn = l.token 1544 name, nameOk := toAbsoluteName(l.token, o) 1545 if l.err || !nameOk { 1546 return &ParseError{"", "bad LP Fqdn", l} 1547 } 1548 rr.Fqdn = name 1549 1550 return slurpRemainder(c) 1551} 1552 1553func (rr *L64) parse(c *zlexer, o string) *ParseError { 1554 l, _ := c.Next() 1555 i, e := strconv.ParseUint(l.token, 10, 16) 1556 if e != nil || l.err { 1557 return &ParseError{"", "bad L64 Preference", l} 1558 } 1559 rr.Preference = uint16(i) 1560 c.Next() // zBlank 1561 l, _ = c.Next() // zString 1562 u, err := stringToNodeID(l) 1563 if err != nil || l.err { 1564 return err 1565 } 1566 rr.Locator64 = u 1567 return slurpRemainder(c) 1568} 1569 1570func (rr *UID) parse(c *zlexer, o string) *ParseError { 1571 l, _ := c.Next() 1572 i, e := strconv.ParseUint(l.token, 10, 32) 1573 if e != nil || l.err { 1574 return &ParseError{"", "bad UID Uid", l} 1575 } 1576 rr.Uid = uint32(i) 1577 return slurpRemainder(c) 1578} 1579 1580func (rr *GID) parse(c *zlexer, o string) *ParseError { 1581 l, _ := c.Next() 1582 i, e := strconv.ParseUint(l.token, 10, 32) 1583 if e != nil || l.err { 1584 return &ParseError{"", "bad GID Gid", l} 1585 } 1586 rr.Gid = uint32(i) 1587 return slurpRemainder(c) 1588} 1589 1590func (rr *UINFO) parse(c *zlexer, o string) *ParseError { 1591 s, e := endingToTxtSlice(c, "bad UINFO Uinfo") 1592 if e != nil { 1593 return e 1594 } 1595 if ln := len(s); ln == 0 { 1596 return nil 1597 } 1598 rr.Uinfo = s[0] // silently discard anything after the first character-string 1599 return nil 1600} 1601 1602func (rr *PX) parse(c *zlexer, o string) *ParseError { 1603 l, _ := c.Next() 1604 i, e := strconv.ParseUint(l.token, 10, 16) 1605 if e != nil || l.err { 1606 return &ParseError{"", "bad PX Preference", l} 1607 } 1608 rr.Preference = uint16(i) 1609 1610 c.Next() // zBlank 1611 l, _ = c.Next() // zString 1612 rr.Map822 = l.token 1613 map822, map822Ok := toAbsoluteName(l.token, o) 1614 if l.err || !map822Ok { 1615 return &ParseError{"", "bad PX Map822", l} 1616 } 1617 rr.Map822 = map822 1618 1619 c.Next() // zBlank 1620 l, _ = c.Next() // zString 1621 rr.Mapx400 = l.token 1622 mapx400, mapx400Ok := toAbsoluteName(l.token, o) 1623 if l.err || !mapx400Ok { 1624 return &ParseError{"", "bad PX Mapx400", l} 1625 } 1626 rr.Mapx400 = mapx400 1627 1628 return slurpRemainder(c) 1629} 1630 1631func (rr *CAA) parse(c *zlexer, o string) *ParseError { 1632 l, _ := c.Next() 1633 i, err := strconv.ParseUint(l.token, 10, 8) 1634 if err != nil || l.err { 1635 return &ParseError{"", "bad CAA Flag", l} 1636 } 1637 rr.Flag = uint8(i) 1638 1639 c.Next() // zBlank 1640 l, _ = c.Next() // zString 1641 if l.value != zString { 1642 return &ParseError{"", "bad CAA Tag", l} 1643 } 1644 rr.Tag = l.token 1645 1646 c.Next() // zBlank 1647 s, e := endingToTxtSlice(c, "bad CAA Value") 1648 if e != nil { 1649 return e 1650 } 1651 if len(s) != 1 { 1652 return &ParseError{"", "bad CAA Value", l} 1653 } 1654 rr.Value = s[0] 1655 return nil 1656} 1657 1658func (rr *TKEY) parse(c *zlexer, o string) *ParseError { 1659 l, _ := c.Next() 1660 1661 // Algorithm 1662 if l.value != zString { 1663 return &ParseError{"", "bad TKEY algorithm", l} 1664 } 1665 rr.Algorithm = l.token 1666 c.Next() // zBlank 1667 1668 // Get the key length and key values 1669 l, _ = c.Next() 1670 i, err := strconv.ParseUint(l.token, 10, 8) 1671 if err != nil || l.err { 1672 return &ParseError{"", "bad TKEY key length", l} 1673 } 1674 rr.KeySize = uint16(i) 1675 c.Next() // zBlank 1676 l, _ = c.Next() 1677 if l.value != zString { 1678 return &ParseError{"", "bad TKEY key", l} 1679 } 1680 rr.Key = l.token 1681 c.Next() // zBlank 1682 1683 // Get the otherdata length and string data 1684 l, _ = c.Next() 1685 i, err = strconv.ParseUint(l.token, 10, 8) 1686 if err != nil || l.err { 1687 return &ParseError{"", "bad TKEY otherdata length", l} 1688 } 1689 rr.OtherLen = uint16(i) 1690 c.Next() // zBlank 1691 l, _ = c.Next() 1692 if l.value != zString { 1693 return &ParseError{"", "bad TKEY otherday", l} 1694 } 1695 rr.OtherData = l.token 1696 1697 return nil 1698} 1699 1700func (rr *APL) parse(c *zlexer, o string) *ParseError { 1701 var prefixes []APLPrefix 1702 1703 for { 1704 l, _ := c.Next() 1705 if l.value == zNewline || l.value == zEOF { 1706 break 1707 } 1708 if l.value == zBlank && prefixes != nil { 1709 continue 1710 } 1711 if l.value != zString { 1712 return &ParseError{"", "unexpected APL field", l} 1713 } 1714 1715 // Expected format: [!]afi:address/prefix 1716 1717 colon := strings.IndexByte(l.token, ':') 1718 if colon == -1 { 1719 return &ParseError{"", "missing colon in APL field", l} 1720 } 1721 1722 family, cidr := l.token[:colon], l.token[colon+1:] 1723 1724 var negation bool 1725 if family != "" && family[0] == '!' { 1726 negation = true 1727 family = family[1:] 1728 } 1729 1730 afi, err := strconv.ParseUint(family, 10, 16) 1731 if err != nil { 1732 return &ParseError{"", "failed to parse APL family: " + err.Error(), l} 1733 } 1734 var addrLen int 1735 switch afi { 1736 case 1: 1737 addrLen = net.IPv4len 1738 case 2: 1739 addrLen = net.IPv6len 1740 default: 1741 return &ParseError{"", "unrecognized APL family", l} 1742 } 1743 1744 ip, subnet, err := net.ParseCIDR(cidr) 1745 if err != nil { 1746 return &ParseError{"", "failed to parse APL address: " + err.Error(), l} 1747 } 1748 if !ip.Equal(subnet.IP) { 1749 return &ParseError{"", "extra bits in APL address", l} 1750 } 1751 1752 if len(subnet.IP) != addrLen { 1753 return &ParseError{"", "address mismatch with the APL family", l} 1754 } 1755 1756 prefixes = append(prefixes, APLPrefix{ 1757 Negation: negation, 1758 Network: *subnet, 1759 }) 1760 } 1761 1762 rr.Prefixes = prefixes 1763 return nil 1764} 1765