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