scan_rr.go raw

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