...

Source file src/github.com/miekg/dns/scan_rr.go

Documentation: github.com/miekg/dns

     1  package dns
     2  
     3  import (
     4  	"encoding/base64"
     5  	"errors"
     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
    13  func endingToString(c *zlexer, errstr string) (string, *ParseError) {
    14  	var s strings.Builder
    15  	l, _ := c.Next() // zString
    16  	for l.value != zNewline && l.value != zEOF {
    17  		if l.err {
    18  			return s.String(), &ParseError{"", errstr, l}
    19  		}
    20  		switch l.value {
    21  		case zString:
    22  			s.WriteString(l.token)
    23  		case zBlank: // Ok
    24  		default:
    25  			return "", &ParseError{"", errstr, l}
    26  		}
    27  		l, _ = c.Next()
    28  	}
    29  
    30  	return s.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
    35  func 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  
    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{"", "bad A A", 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{"", "bad AAAA AAAA", 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{"", "bad NS Ns", 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{"", "bad PTR Ptr", 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{"", "bad NSAP-PTR Ptr", 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{"", "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  
   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{"", "bad MR Mr", 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{"", "bad MB Mb", 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{"", "bad MG Mg", 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  
   223  	return nil
   224  }
   225  
   226  func (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  
   247  func (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  
   257  func (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  
   267  func (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  
   288  func (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  
   309  func (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  
   329  func (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  
   338  func (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  
   358  func (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  
   368  func (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  
   378  func (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  
   440  func (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  
   476  func (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  
   562  func (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  
   583  func (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  
   626  East:
   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  
   662  Altitude:
   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  
   714  func (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  	decodedPK, decodedPKerr := base64.StdEncoding.DecodeString(rr.PublicKey)
   738  	if decodedPKerr != nil {
   739  		return &ParseError{"", "bad HIP PublicKey", l}
   740  	}
   741  	rr.PublicKeyLength = uint16(len(decodedPK))
   742  
   743  	// RendezvousServers (if any)
   744  	l, _ = c.Next()
   745  	var xs []string
   746  	for l.value != zNewline && l.value != zEOF {
   747  		switch l.value {
   748  		case zString:
   749  			name, nameOk := toAbsoluteName(l.token, o)
   750  			if l.err || !nameOk {
   751  				return &ParseError{"", "bad HIP RendezvousServers", l}
   752  			}
   753  			xs = append(xs, name)
   754  		case zBlank:
   755  			// Ok
   756  		default:
   757  			return &ParseError{"", "bad HIP RendezvousServers", l}
   758  		}
   759  		l, _ = c.Next()
   760  	}
   761  
   762  	rr.RendezvousServers = xs
   763  	return nil
   764  }
   765  
   766  func (rr *CERT) parse(c *zlexer, o string) *ParseError {
   767  	l, _ := c.Next()
   768  	if v, ok := StringToCertType[l.token]; ok {
   769  		rr.Type = v
   770  	} else if i, err := strconv.ParseUint(l.token, 10, 16); err != nil {
   771  		return &ParseError{"", "bad CERT Type", l}
   772  	} else {
   773  		rr.Type = uint16(i)
   774  	}
   775  	c.Next()        // zBlank
   776  	l, _ = c.Next() // zString
   777  	i, e := strconv.ParseUint(l.token, 10, 16)
   778  	if e != nil || l.err {
   779  		return &ParseError{"", "bad CERT KeyTag", l}
   780  	}
   781  	rr.KeyTag = uint16(i)
   782  	c.Next()        // zBlank
   783  	l, _ = c.Next() // zString
   784  	if v, ok := StringToAlgorithm[l.token]; ok {
   785  		rr.Algorithm = v
   786  	} else if i, err := strconv.ParseUint(l.token, 10, 8); err != nil {
   787  		return &ParseError{"", "bad CERT Algorithm", l}
   788  	} else {
   789  		rr.Algorithm = uint8(i)
   790  	}
   791  	s, e1 := endingToString(c, "bad CERT Certificate")
   792  	if e1 != nil {
   793  		return e1
   794  	}
   795  	rr.Certificate = s
   796  	return nil
   797  }
   798  
   799  func (rr *OPENPGPKEY) parse(c *zlexer, o string) *ParseError {
   800  	s, e := endingToString(c, "bad OPENPGPKEY PublicKey")
   801  	if e != nil {
   802  		return e
   803  	}
   804  	rr.PublicKey = s
   805  	return nil
   806  }
   807  
   808  func (rr *CSYNC) parse(c *zlexer, o string) *ParseError {
   809  	l, _ := c.Next()
   810  	j, e := strconv.ParseUint(l.token, 10, 32)
   811  	if e != nil {
   812  		// Serial must be a number
   813  		return &ParseError{"", "bad CSYNC serial", l}
   814  	}
   815  	rr.Serial = uint32(j)
   816  
   817  	c.Next() // zBlank
   818  
   819  	l, _ = c.Next()
   820  	j, e1 := strconv.ParseUint(l.token, 10, 16)
   821  	if e1 != nil {
   822  		// Serial must be a number
   823  		return &ParseError{"", "bad CSYNC flags", l}
   824  	}
   825  	rr.Flags = uint16(j)
   826  
   827  	rr.TypeBitMap = make([]uint16, 0)
   828  	var (
   829  		k  uint16
   830  		ok bool
   831  	)
   832  	l, _ = c.Next()
   833  	for l.value != zNewline && l.value != zEOF {
   834  		switch l.value {
   835  		case zBlank:
   836  			// Ok
   837  		case zString:
   838  			tokenUpper := strings.ToUpper(l.token)
   839  			if k, ok = StringToType[tokenUpper]; !ok {
   840  				if k, ok = typeToInt(l.token); !ok {
   841  					return &ParseError{"", "bad CSYNC TypeBitMap", l}
   842  				}
   843  			}
   844  			rr.TypeBitMap = append(rr.TypeBitMap, k)
   845  		default:
   846  			return &ParseError{"", "bad CSYNC TypeBitMap", l}
   847  		}
   848  		l, _ = c.Next()
   849  	}
   850  	return nil
   851  }
   852  
   853  func (rr *ZONEMD) parse(c *zlexer, o string) *ParseError {
   854  	l, _ := c.Next()
   855  	i, e := strconv.ParseUint(l.token, 10, 32)
   856  	if e != nil || l.err {
   857  		return &ParseError{"", "bad ZONEMD Serial", l}
   858  	}
   859  	rr.Serial = uint32(i)
   860  
   861  	c.Next() // zBlank
   862  	l, _ = c.Next()
   863  	i, e1 := strconv.ParseUint(l.token, 10, 8)
   864  	if e1 != nil || l.err {
   865  		return &ParseError{"", "bad ZONEMD Scheme", l}
   866  	}
   867  	rr.Scheme = uint8(i)
   868  
   869  	c.Next() // zBlank
   870  	l, _ = c.Next()
   871  	i, err := strconv.ParseUint(l.token, 10, 8)
   872  	if err != nil || l.err {
   873  		return &ParseError{"", "bad ZONEMD Hash Algorithm", l}
   874  	}
   875  	rr.Hash = uint8(i)
   876  
   877  	s, e2 := endingToString(c, "bad ZONEMD Digest")
   878  	if e2 != nil {
   879  		return e2
   880  	}
   881  	rr.Digest = s
   882  	return nil
   883  }
   884  
   885  func (rr *SIG) parse(c *zlexer, o string) *ParseError { return rr.RRSIG.parse(c, o) }
   886  
   887  func (rr *RRSIG) parse(c *zlexer, o string) *ParseError {
   888  	l, _ := c.Next()
   889  	tokenUpper := strings.ToUpper(l.token)
   890  	if t, ok := StringToType[tokenUpper]; !ok {
   891  		if strings.HasPrefix(tokenUpper, "TYPE") {
   892  			t, ok = typeToInt(l.token)
   893  			if !ok {
   894  				return &ParseError{"", "bad RRSIG Typecovered", l}
   895  			}
   896  			rr.TypeCovered = t
   897  		} else {
   898  			return &ParseError{"", "bad RRSIG Typecovered", l}
   899  		}
   900  	} else {
   901  		rr.TypeCovered = t
   902  	}
   903  
   904  	c.Next() // zBlank
   905  	l, _ = c.Next()
   906  	if l.err {
   907  		return &ParseError{"", "bad RRSIG Algorithm", l}
   908  	}
   909  	i, e := strconv.ParseUint(l.token, 10, 8)
   910  	rr.Algorithm = uint8(i) // if 0 we'll check the mnemonic in the if
   911  	if e != nil {
   912  		v, ok := StringToAlgorithm[l.token]
   913  		if !ok {
   914  			return &ParseError{"", "bad RRSIG Algorithm", l}
   915  		}
   916  		rr.Algorithm = v
   917  	}
   918  
   919  	c.Next() // zBlank
   920  	l, _ = c.Next()
   921  	i, e1 := strconv.ParseUint(l.token, 10, 8)
   922  	if e1 != nil || l.err {
   923  		return &ParseError{"", "bad RRSIG Labels", l}
   924  	}
   925  	rr.Labels = uint8(i)
   926  
   927  	c.Next() // zBlank
   928  	l, _ = c.Next()
   929  	i, e2 := strconv.ParseUint(l.token, 10, 32)
   930  	if e2 != nil || l.err {
   931  		return &ParseError{"", "bad RRSIG OrigTtl", l}
   932  	}
   933  	rr.OrigTtl = uint32(i)
   934  
   935  	c.Next() // zBlank
   936  	l, _ = c.Next()
   937  	if i, err := StringToTime(l.token); err != nil {
   938  		// Try to see if all numeric and use it as epoch
   939  		if i, err := strconv.ParseUint(l.token, 10, 32); err == nil {
   940  			rr.Expiration = uint32(i)
   941  		} else {
   942  			return &ParseError{"", "bad RRSIG Expiration", l}
   943  		}
   944  	} else {
   945  		rr.Expiration = i
   946  	}
   947  
   948  	c.Next() // zBlank
   949  	l, _ = c.Next()
   950  	if i, err := StringToTime(l.token); err != nil {
   951  		if i, err := strconv.ParseUint(l.token, 10, 32); err == nil {
   952  			rr.Inception = uint32(i)
   953  		} else {
   954  			return &ParseError{"", "bad RRSIG Inception", l}
   955  		}
   956  	} else {
   957  		rr.Inception = i
   958  	}
   959  
   960  	c.Next() // zBlank
   961  	l, _ = c.Next()
   962  	i, e3 := strconv.ParseUint(l.token, 10, 16)
   963  	if e3 != nil || l.err {
   964  		return &ParseError{"", "bad RRSIG KeyTag", l}
   965  	}
   966  	rr.KeyTag = uint16(i)
   967  
   968  	c.Next() // zBlank
   969  	l, _ = c.Next()
   970  	rr.SignerName = l.token
   971  	name, nameOk := toAbsoluteName(l.token, o)
   972  	if l.err || !nameOk {
   973  		return &ParseError{"", "bad RRSIG SignerName", l}
   974  	}
   975  	rr.SignerName = name
   976  
   977  	s, e4 := endingToString(c, "bad RRSIG Signature")
   978  	if e4 != nil {
   979  		return e4
   980  	}
   981  	rr.Signature = s
   982  
   983  	return nil
   984  }
   985  
   986  func (rr *NSEC) parse(c *zlexer, o string) *ParseError {
   987  	l, _ := c.Next()
   988  	name, nameOk := toAbsoluteName(l.token, o)
   989  	if l.err || !nameOk {
   990  		return &ParseError{"", "bad NSEC NextDomain", l}
   991  	}
   992  	rr.NextDomain = name
   993  
   994  	rr.TypeBitMap = make([]uint16, 0)
   995  	var (
   996  		k  uint16
   997  		ok bool
   998  	)
   999  	l, _ = c.Next()
  1000  	for l.value != zNewline && l.value != zEOF {
  1001  		switch l.value {
  1002  		case zBlank:
  1003  			// Ok
  1004  		case zString:
  1005  			tokenUpper := strings.ToUpper(l.token)
  1006  			if k, ok = StringToType[tokenUpper]; !ok {
  1007  				if k, ok = typeToInt(l.token); !ok {
  1008  					return &ParseError{"", "bad NSEC TypeBitMap", l}
  1009  				}
  1010  			}
  1011  			rr.TypeBitMap = append(rr.TypeBitMap, k)
  1012  		default:
  1013  			return &ParseError{"", "bad NSEC TypeBitMap", l}
  1014  		}
  1015  		l, _ = c.Next()
  1016  	}
  1017  	return nil
  1018  }
  1019  
  1020  func (rr *NSEC3) parse(c *zlexer, o string) *ParseError {
  1021  	l, _ := c.Next()
  1022  	i, e := strconv.ParseUint(l.token, 10, 8)
  1023  	if e != nil || l.err {
  1024  		return &ParseError{"", "bad NSEC3 Hash", l}
  1025  	}
  1026  	rr.Hash = uint8(i)
  1027  	c.Next() // zBlank
  1028  	l, _ = c.Next()
  1029  	i, e1 := strconv.ParseUint(l.token, 10, 8)
  1030  	if e1 != nil || l.err {
  1031  		return &ParseError{"", "bad NSEC3 Flags", l}
  1032  	}
  1033  	rr.Flags = uint8(i)
  1034  	c.Next() // zBlank
  1035  	l, _ = c.Next()
  1036  	i, e2 := strconv.ParseUint(l.token, 10, 16)
  1037  	if e2 != nil || l.err {
  1038  		return &ParseError{"", "bad NSEC3 Iterations", l}
  1039  	}
  1040  	rr.Iterations = uint16(i)
  1041  	c.Next()
  1042  	l, _ = c.Next()
  1043  	if l.token == "" || l.err {
  1044  		return &ParseError{"", "bad NSEC3 Salt", l}
  1045  	}
  1046  	if l.token != "-" {
  1047  		rr.SaltLength = uint8(len(l.token)) / 2
  1048  		rr.Salt = l.token
  1049  	}
  1050  
  1051  	c.Next()
  1052  	l, _ = c.Next()
  1053  	if l.token == "" || l.err {
  1054  		return &ParseError{"", "bad NSEC3 NextDomain", l}
  1055  	}
  1056  	rr.HashLength = 20 // Fix for NSEC3 (sha1 160 bits)
  1057  	rr.NextDomain = l.token
  1058  
  1059  	rr.TypeBitMap = make([]uint16, 0)
  1060  	var (
  1061  		k  uint16
  1062  		ok bool
  1063  	)
  1064  	l, _ = c.Next()
  1065  	for l.value != zNewline && l.value != zEOF {
  1066  		switch l.value {
  1067  		case zBlank:
  1068  			// Ok
  1069  		case zString:
  1070  			tokenUpper := strings.ToUpper(l.token)
  1071  			if k, ok = StringToType[tokenUpper]; !ok {
  1072  				if k, ok = typeToInt(l.token); !ok {
  1073  					return &ParseError{"", "bad NSEC3 TypeBitMap", l}
  1074  				}
  1075  			}
  1076  			rr.TypeBitMap = append(rr.TypeBitMap, k)
  1077  		default:
  1078  			return &ParseError{"", "bad NSEC3 TypeBitMap", l}
  1079  		}
  1080  		l, _ = c.Next()
  1081  	}
  1082  	return nil
  1083  }
  1084  
  1085  func (rr *NSEC3PARAM) parse(c *zlexer, o string) *ParseError {
  1086  	l, _ := c.Next()
  1087  	i, e := strconv.ParseUint(l.token, 10, 8)
  1088  	if e != nil || l.err {
  1089  		return &ParseError{"", "bad NSEC3PARAM Hash", l}
  1090  	}
  1091  	rr.Hash = uint8(i)
  1092  	c.Next() // zBlank
  1093  	l, _ = c.Next()
  1094  	i, e1 := strconv.ParseUint(l.token, 10, 8)
  1095  	if e1 != nil || l.err {
  1096  		return &ParseError{"", "bad NSEC3PARAM Flags", l}
  1097  	}
  1098  	rr.Flags = uint8(i)
  1099  	c.Next() // zBlank
  1100  	l, _ = c.Next()
  1101  	i, e2 := strconv.ParseUint(l.token, 10, 16)
  1102  	if e2 != nil || l.err {
  1103  		return &ParseError{"", "bad NSEC3PARAM Iterations", l}
  1104  	}
  1105  	rr.Iterations = uint16(i)
  1106  	c.Next()
  1107  	l, _ = c.Next()
  1108  	if l.token != "-" {
  1109  		rr.SaltLength = uint8(len(l.token) / 2)
  1110  		rr.Salt = l.token
  1111  	}
  1112  	return slurpRemainder(c)
  1113  }
  1114  
  1115  func (rr *EUI48) parse(c *zlexer, o string) *ParseError {
  1116  	l, _ := c.Next()
  1117  	if len(l.token) != 17 || l.err {
  1118  		return &ParseError{"", "bad EUI48 Address", l}
  1119  	}
  1120  	addr := make([]byte, 12)
  1121  	dash := 0
  1122  	for i := 0; i < 10; i += 2 {
  1123  		addr[i] = l.token[i+dash]
  1124  		addr[i+1] = l.token[i+1+dash]
  1125  		dash++
  1126  		if l.token[i+1+dash] != '-' {
  1127  			return &ParseError{"", "bad EUI48 Address", l}
  1128  		}
  1129  	}
  1130  	addr[10] = l.token[15]
  1131  	addr[11] = l.token[16]
  1132  
  1133  	i, e := strconv.ParseUint(string(addr), 16, 48)
  1134  	if e != nil {
  1135  		return &ParseError{"", "bad EUI48 Address", l}
  1136  	}
  1137  	rr.Address = i
  1138  	return slurpRemainder(c)
  1139  }
  1140  
  1141  func (rr *EUI64) parse(c *zlexer, o string) *ParseError {
  1142  	l, _ := c.Next()
  1143  	if len(l.token) != 23 || l.err {
  1144  		return &ParseError{"", "bad EUI64 Address", l}
  1145  	}
  1146  	addr := make([]byte, 16)
  1147  	dash := 0
  1148  	for i := 0; i < 14; i += 2 {
  1149  		addr[i] = l.token[i+dash]
  1150  		addr[i+1] = l.token[i+1+dash]
  1151  		dash++
  1152  		if l.token[i+1+dash] != '-' {
  1153  			return &ParseError{"", "bad EUI64 Address", l}
  1154  		}
  1155  	}
  1156  	addr[14] = l.token[21]
  1157  	addr[15] = l.token[22]
  1158  
  1159  	i, e := strconv.ParseUint(string(addr), 16, 64)
  1160  	if e != nil {
  1161  		return &ParseError{"", "bad EUI68 Address", l}
  1162  	}
  1163  	rr.Address = i
  1164  	return slurpRemainder(c)
  1165  }
  1166  
  1167  func (rr *SSHFP) parse(c *zlexer, o string) *ParseError {
  1168  	l, _ := c.Next()
  1169  	i, e := strconv.ParseUint(l.token, 10, 8)
  1170  	if e != nil || l.err {
  1171  		return &ParseError{"", "bad SSHFP Algorithm", l}
  1172  	}
  1173  	rr.Algorithm = uint8(i)
  1174  	c.Next() // zBlank
  1175  	l, _ = c.Next()
  1176  	i, e1 := strconv.ParseUint(l.token, 10, 8)
  1177  	if e1 != nil || l.err {
  1178  		return &ParseError{"", "bad SSHFP Type", l}
  1179  	}
  1180  	rr.Type = uint8(i)
  1181  	c.Next() // zBlank
  1182  	s, e2 := endingToString(c, "bad SSHFP Fingerprint")
  1183  	if e2 != nil {
  1184  		return e2
  1185  	}
  1186  	rr.FingerPrint = s
  1187  	return nil
  1188  }
  1189  
  1190  func (rr *DNSKEY) parseDNSKEY(c *zlexer, o, typ string) *ParseError {
  1191  	l, _ := c.Next()
  1192  	i, e := strconv.ParseUint(l.token, 10, 16)
  1193  	if e != nil || l.err {
  1194  		return &ParseError{"", "bad " + typ + " Flags", l}
  1195  	}
  1196  	rr.Flags = uint16(i)
  1197  	c.Next()        // zBlank
  1198  	l, _ = c.Next() // zString
  1199  	i, e1 := strconv.ParseUint(l.token, 10, 8)
  1200  	if e1 != nil || l.err {
  1201  		return &ParseError{"", "bad " + typ + " Protocol", l}
  1202  	}
  1203  	rr.Protocol = uint8(i)
  1204  	c.Next()        // zBlank
  1205  	l, _ = c.Next() // zString
  1206  	i, e2 := strconv.ParseUint(l.token, 10, 8)
  1207  	if e2 != nil || l.err {
  1208  		return &ParseError{"", "bad " + typ + " Algorithm", l}
  1209  	}
  1210  	rr.Algorithm = uint8(i)
  1211  	s, e3 := endingToString(c, "bad "+typ+" PublicKey")
  1212  	if e3 != nil {
  1213  		return e3
  1214  	}
  1215  	rr.PublicKey = s
  1216  	return nil
  1217  }
  1218  
  1219  func (rr *DNSKEY) parse(c *zlexer, o string) *ParseError  { return rr.parseDNSKEY(c, o, "DNSKEY") }
  1220  func (rr *KEY) parse(c *zlexer, o string) *ParseError     { return rr.parseDNSKEY(c, o, "KEY") }
  1221  func (rr *CDNSKEY) parse(c *zlexer, o string) *ParseError { return rr.parseDNSKEY(c, o, "CDNSKEY") }
  1222  func (rr *DS) parse(c *zlexer, o string) *ParseError      { return rr.parseDS(c, o, "DS") }
  1223  func (rr *DLV) parse(c *zlexer, o string) *ParseError     { return rr.parseDS(c, o, "DLV") }
  1224  func (rr *CDS) parse(c *zlexer, o string) *ParseError     { return rr.parseDS(c, o, "CDS") }
  1225  
  1226  func (rr *IPSECKEY) parse(c *zlexer, o string) *ParseError {
  1227  	l, _ := c.Next()
  1228  	num, err := strconv.ParseUint(l.token, 10, 8)
  1229  	if err != nil || l.err {
  1230  		return &ParseError{"", "bad IPSECKEY value", l}
  1231  	}
  1232  	rr.Precedence = uint8(num)
  1233  	c.Next() // zBlank
  1234  
  1235  	l, _ = c.Next()
  1236  	num, err = strconv.ParseUint(l.token, 10, 8)
  1237  	if err != nil || l.err {
  1238  		return &ParseError{"", "bad IPSECKEY value", l}
  1239  	}
  1240  	rr.GatewayType = uint8(num)
  1241  	c.Next() // zBlank
  1242  
  1243  	l, _ = c.Next()
  1244  	num, err = strconv.ParseUint(l.token, 10, 8)
  1245  	if err != nil || l.err {
  1246  		return &ParseError{"", "bad IPSECKEY value", l}
  1247  	}
  1248  	rr.Algorithm = uint8(num)
  1249  	c.Next() // zBlank
  1250  
  1251  	l, _ = c.Next()
  1252  	if l.err {
  1253  		return &ParseError{"", "bad IPSECKEY gateway", l}
  1254  	}
  1255  
  1256  	rr.GatewayAddr, rr.GatewayHost, err = parseAddrHostUnion(l.token, o, rr.GatewayType)
  1257  	if err != nil {
  1258  		return &ParseError{"", "IPSECKEY " + err.Error(), l}
  1259  	}
  1260  
  1261  	c.Next() // zBlank
  1262  
  1263  	s, pErr := endingToString(c, "bad IPSECKEY PublicKey")
  1264  	if pErr != nil {
  1265  		return pErr
  1266  	}
  1267  	rr.PublicKey = s
  1268  	return slurpRemainder(c)
  1269  }
  1270  
  1271  func (rr *AMTRELAY) parse(c *zlexer, o string) *ParseError {
  1272  	l, _ := c.Next()
  1273  	num, err := strconv.ParseUint(l.token, 10, 8)
  1274  	if err != nil || l.err {
  1275  		return &ParseError{"", "bad AMTRELAY value", l}
  1276  	}
  1277  	rr.Precedence = uint8(num)
  1278  	c.Next() // zBlank
  1279  
  1280  	l, _ = c.Next()
  1281  	if l.err || !(l.token == "0" || l.token == "1") {
  1282  		return &ParseError{"", "bad discovery value", l}
  1283  	}
  1284  	if l.token == "1" {
  1285  		rr.GatewayType = 0x80
  1286  	}
  1287  
  1288  	c.Next() // zBlank
  1289  
  1290  	l, _ = c.Next()
  1291  	num, err = strconv.ParseUint(l.token, 10, 8)
  1292  	if err != nil || l.err {
  1293  		return &ParseError{"", "bad AMTRELAY value", l}
  1294  	}
  1295  	rr.GatewayType |= uint8(num)
  1296  	c.Next() // zBlank
  1297  
  1298  	l, _ = c.Next()
  1299  	if l.err {
  1300  		return &ParseError{"", "bad AMTRELAY gateway", l}
  1301  	}
  1302  
  1303  	rr.GatewayAddr, rr.GatewayHost, err = parseAddrHostUnion(l.token, o, rr.GatewayType&0x7f)
  1304  	if err != nil {
  1305  		return &ParseError{"", "AMTRELAY " + err.Error(), l}
  1306  	}
  1307  
  1308  	return slurpRemainder(c)
  1309  }
  1310  
  1311  // same constants and parsing between IPSECKEY and AMTRELAY
  1312  func parseAddrHostUnion(token, o string, gatewayType uint8) (addr net.IP, host string, err error) {
  1313  	switch gatewayType {
  1314  	case IPSECGatewayNone:
  1315  		if token != "." {
  1316  			return addr, host, errors.New("gateway type none with gateway set")
  1317  		}
  1318  	case IPSECGatewayIPv4, IPSECGatewayIPv6:
  1319  		addr = net.ParseIP(token)
  1320  		if addr == nil {
  1321  			return addr, host, errors.New("gateway IP invalid")
  1322  		}
  1323  		if (addr.To4() == nil) == (gatewayType == IPSECGatewayIPv4) {
  1324  			return addr, host, errors.New("gateway IP family mismatch")
  1325  		}
  1326  	case IPSECGatewayHost:
  1327  		var ok bool
  1328  		host, ok = toAbsoluteName(token, o)
  1329  		if !ok {
  1330  			return addr, host, errors.New("invalid gateway host")
  1331  		}
  1332  	}
  1333  
  1334  	return addr, host, nil
  1335  }
  1336  
  1337  func (rr *RKEY) parse(c *zlexer, o string) *ParseError {
  1338  	l, _ := c.Next()
  1339  	i, e := strconv.ParseUint(l.token, 10, 16)
  1340  	if e != nil || l.err {
  1341  		return &ParseError{"", "bad RKEY Flags", l}
  1342  	}
  1343  	rr.Flags = uint16(i)
  1344  	c.Next()        // zBlank
  1345  	l, _ = c.Next() // zString
  1346  	i, e1 := strconv.ParseUint(l.token, 10, 8)
  1347  	if e1 != nil || l.err {
  1348  		return &ParseError{"", "bad RKEY Protocol", l}
  1349  	}
  1350  	rr.Protocol = uint8(i)
  1351  	c.Next()        // zBlank
  1352  	l, _ = c.Next() // zString
  1353  	i, e2 := strconv.ParseUint(l.token, 10, 8)
  1354  	if e2 != nil || l.err {
  1355  		return &ParseError{"", "bad RKEY Algorithm", l}
  1356  	}
  1357  	rr.Algorithm = uint8(i)
  1358  	s, e3 := endingToString(c, "bad RKEY PublicKey")
  1359  	if e3 != nil {
  1360  		return e3
  1361  	}
  1362  	rr.PublicKey = s
  1363  	return nil
  1364  }
  1365  
  1366  func (rr *EID) parse(c *zlexer, o string) *ParseError {
  1367  	s, e := endingToString(c, "bad EID Endpoint")
  1368  	if e != nil {
  1369  		return e
  1370  	}
  1371  	rr.Endpoint = s
  1372  	return nil
  1373  }
  1374  
  1375  func (rr *NIMLOC) parse(c *zlexer, o string) *ParseError {
  1376  	s, e := endingToString(c, "bad NIMLOC Locator")
  1377  	if e != nil {
  1378  		return e
  1379  	}
  1380  	rr.Locator = s
  1381  	return nil
  1382  }
  1383  
  1384  func (rr *GPOS) parse(c *zlexer, o string) *ParseError {
  1385  	l, _ := c.Next()
  1386  	_, e := strconv.ParseFloat(l.token, 64)
  1387  	if e != nil || l.err {
  1388  		return &ParseError{"", "bad GPOS Longitude", l}
  1389  	}
  1390  	rr.Longitude = l.token
  1391  	c.Next() // zBlank
  1392  	l, _ = c.Next()
  1393  	_, e1 := strconv.ParseFloat(l.token, 64)
  1394  	if e1 != nil || l.err {
  1395  		return &ParseError{"", "bad GPOS Latitude", l}
  1396  	}
  1397  	rr.Latitude = l.token
  1398  	c.Next() // zBlank
  1399  	l, _ = c.Next()
  1400  	_, e2 := strconv.ParseFloat(l.token, 64)
  1401  	if e2 != nil || l.err {
  1402  		return &ParseError{"", "bad GPOS Altitude", l}
  1403  	}
  1404  	rr.Altitude = l.token
  1405  	return slurpRemainder(c)
  1406  }
  1407  
  1408  func (rr *DS) parseDS(c *zlexer, o, typ string) *ParseError {
  1409  	l, _ := c.Next()
  1410  	i, e := strconv.ParseUint(l.token, 10, 16)
  1411  	if e != nil || l.err {
  1412  		return &ParseError{"", "bad " + typ + " KeyTag", l}
  1413  	}
  1414  	rr.KeyTag = uint16(i)
  1415  	c.Next() // zBlank
  1416  	l, _ = c.Next()
  1417  	if i, err := strconv.ParseUint(l.token, 10, 8); err != nil {
  1418  		tokenUpper := strings.ToUpper(l.token)
  1419  		i, ok := StringToAlgorithm[tokenUpper]
  1420  		if !ok || l.err {
  1421  			return &ParseError{"", "bad " + typ + " Algorithm", l}
  1422  		}
  1423  		rr.Algorithm = i
  1424  	} else {
  1425  		rr.Algorithm = uint8(i)
  1426  	}
  1427  	c.Next() // zBlank
  1428  	l, _ = c.Next()
  1429  	i, e1 := strconv.ParseUint(l.token, 10, 8)
  1430  	if e1 != nil || l.err {
  1431  		return &ParseError{"", "bad " + typ + " DigestType", l}
  1432  	}
  1433  	rr.DigestType = uint8(i)
  1434  	s, e2 := endingToString(c, "bad "+typ+" Digest")
  1435  	if e2 != nil {
  1436  		return e2
  1437  	}
  1438  	rr.Digest = s
  1439  	return nil
  1440  }
  1441  
  1442  func (rr *TA) parse(c *zlexer, o string) *ParseError {
  1443  	l, _ := c.Next()
  1444  	i, e := strconv.ParseUint(l.token, 10, 16)
  1445  	if e != nil || l.err {
  1446  		return &ParseError{"", "bad TA KeyTag", l}
  1447  	}
  1448  	rr.KeyTag = uint16(i)
  1449  	c.Next() // zBlank
  1450  	l, _ = c.Next()
  1451  	if i, err := strconv.ParseUint(l.token, 10, 8); err != nil {
  1452  		tokenUpper := strings.ToUpper(l.token)
  1453  		i, ok := StringToAlgorithm[tokenUpper]
  1454  		if !ok || l.err {
  1455  			return &ParseError{"", "bad TA Algorithm", l}
  1456  		}
  1457  		rr.Algorithm = i
  1458  	} else {
  1459  		rr.Algorithm = uint8(i)
  1460  	}
  1461  	c.Next() // zBlank
  1462  	l, _ = c.Next()
  1463  	i, e1 := strconv.ParseUint(l.token, 10, 8)
  1464  	if e1 != nil || l.err {
  1465  		return &ParseError{"", "bad TA DigestType", l}
  1466  	}
  1467  	rr.DigestType = uint8(i)
  1468  	s, e2 := endingToString(c, "bad TA Digest")
  1469  	if e2 != nil {
  1470  		return e2
  1471  	}
  1472  	rr.Digest = s
  1473  	return nil
  1474  }
  1475  
  1476  func (rr *TLSA) parse(c *zlexer, o string) *ParseError {
  1477  	l, _ := c.Next()
  1478  	i, e := strconv.ParseUint(l.token, 10, 8)
  1479  	if e != nil || l.err {
  1480  		return &ParseError{"", "bad TLSA Usage", l}
  1481  	}
  1482  	rr.Usage = uint8(i)
  1483  	c.Next() // zBlank
  1484  	l, _ = c.Next()
  1485  	i, e1 := strconv.ParseUint(l.token, 10, 8)
  1486  	if e1 != nil || l.err {
  1487  		return &ParseError{"", "bad TLSA Selector", l}
  1488  	}
  1489  	rr.Selector = uint8(i)
  1490  	c.Next() // zBlank
  1491  	l, _ = c.Next()
  1492  	i, e2 := strconv.ParseUint(l.token, 10, 8)
  1493  	if e2 != nil || l.err {
  1494  		return &ParseError{"", "bad TLSA MatchingType", l}
  1495  	}
  1496  	rr.MatchingType = uint8(i)
  1497  	// So this needs be e2 (i.e. different than e), because...??t
  1498  	s, e3 := endingToString(c, "bad TLSA Certificate")
  1499  	if e3 != nil {
  1500  		return e3
  1501  	}
  1502  	rr.Certificate = s
  1503  	return nil
  1504  }
  1505  
  1506  func (rr *SMIMEA) parse(c *zlexer, o string) *ParseError {
  1507  	l, _ := c.Next()
  1508  	i, e := strconv.ParseUint(l.token, 10, 8)
  1509  	if e != nil || l.err {
  1510  		return &ParseError{"", "bad SMIMEA Usage", l}
  1511  	}
  1512  	rr.Usage = uint8(i)
  1513  	c.Next() // zBlank
  1514  	l, _ = c.Next()
  1515  	i, e1 := strconv.ParseUint(l.token, 10, 8)
  1516  	if e1 != nil || l.err {
  1517  		return &ParseError{"", "bad SMIMEA Selector", l}
  1518  	}
  1519  	rr.Selector = uint8(i)
  1520  	c.Next() // zBlank
  1521  	l, _ = c.Next()
  1522  	i, e2 := strconv.ParseUint(l.token, 10, 8)
  1523  	if e2 != nil || l.err {
  1524  		return &ParseError{"", "bad SMIMEA MatchingType", l}
  1525  	}
  1526  	rr.MatchingType = uint8(i)
  1527  	// So this needs be e2 (i.e. different than e), because...??t
  1528  	s, e3 := endingToString(c, "bad SMIMEA Certificate")
  1529  	if e3 != nil {
  1530  		return e3
  1531  	}
  1532  	rr.Certificate = s
  1533  	return nil
  1534  }
  1535  
  1536  func (rr *RFC3597) parse(c *zlexer, o string) *ParseError {
  1537  	l, _ := c.Next()
  1538  	if l.token != "\\#" {
  1539  		return &ParseError{"", "bad RFC3597 Rdata", l}
  1540  	}
  1541  
  1542  	c.Next() // zBlank
  1543  	l, _ = c.Next()
  1544  	rdlength, e := strconv.ParseUint(l.token, 10, 16)
  1545  	if e != nil || l.err {
  1546  		return &ParseError{"", "bad RFC3597 Rdata ", l}
  1547  	}
  1548  
  1549  	s, e1 := endingToString(c, "bad RFC3597 Rdata")
  1550  	if e1 != nil {
  1551  		return e1
  1552  	}
  1553  	if int(rdlength)*2 != len(s) {
  1554  		return &ParseError{"", "bad RFC3597 Rdata", l}
  1555  	}
  1556  	rr.Rdata = s
  1557  	return nil
  1558  }
  1559  
  1560  func (rr *SPF) parse(c *zlexer, o string) *ParseError {
  1561  	s, e := endingToTxtSlice(c, "bad SPF Txt")
  1562  	if e != nil {
  1563  		return e
  1564  	}
  1565  	rr.Txt = s
  1566  	return nil
  1567  }
  1568  
  1569  func (rr *AVC) parse(c *zlexer, o string) *ParseError {
  1570  	s, e := endingToTxtSlice(c, "bad AVC Txt")
  1571  	if e != nil {
  1572  		return e
  1573  	}
  1574  	rr.Txt = s
  1575  	return nil
  1576  }
  1577  
  1578  func (rr *TXT) parse(c *zlexer, o string) *ParseError {
  1579  	// no zBlank reading here, because all this rdata is TXT
  1580  	s, e := endingToTxtSlice(c, "bad TXT Txt")
  1581  	if e != nil {
  1582  		return e
  1583  	}
  1584  	rr.Txt = s
  1585  	return nil
  1586  }
  1587  
  1588  // identical to setTXT
  1589  func (rr *NINFO) parse(c *zlexer, o string) *ParseError {
  1590  	s, e := endingToTxtSlice(c, "bad NINFO ZSData")
  1591  	if e != nil {
  1592  		return e
  1593  	}
  1594  	rr.ZSData = s
  1595  	return nil
  1596  }
  1597  
  1598  func (rr *URI) parse(c *zlexer, o string) *ParseError {
  1599  	l, _ := c.Next()
  1600  	i, e := strconv.ParseUint(l.token, 10, 16)
  1601  	if e != nil || l.err {
  1602  		return &ParseError{"", "bad URI Priority", l}
  1603  	}
  1604  	rr.Priority = uint16(i)
  1605  	c.Next() // zBlank
  1606  	l, _ = c.Next()
  1607  	i, e1 := strconv.ParseUint(l.token, 10, 16)
  1608  	if e1 != nil || l.err {
  1609  		return &ParseError{"", "bad URI Weight", l}
  1610  	}
  1611  	rr.Weight = uint16(i)
  1612  
  1613  	c.Next() // zBlank
  1614  	s, e2 := endingToTxtSlice(c, "bad URI Target")
  1615  	if e2 != nil {
  1616  		return e2
  1617  	}
  1618  	if len(s) != 1 {
  1619  		return &ParseError{"", "bad URI Target", l}
  1620  	}
  1621  	rr.Target = s[0]
  1622  	return nil
  1623  }
  1624  
  1625  func (rr *DHCID) parse(c *zlexer, o string) *ParseError {
  1626  	// awesome record to parse!
  1627  	s, e := endingToString(c, "bad DHCID Digest")
  1628  	if e != nil {
  1629  		return e
  1630  	}
  1631  	rr.Digest = s
  1632  	return nil
  1633  }
  1634  
  1635  func (rr *NID) parse(c *zlexer, o string) *ParseError {
  1636  	l, _ := c.Next()
  1637  	i, e := strconv.ParseUint(l.token, 10, 16)
  1638  	if e != nil || l.err {
  1639  		return &ParseError{"", "bad NID Preference", l}
  1640  	}
  1641  	rr.Preference = uint16(i)
  1642  	c.Next()        // zBlank
  1643  	l, _ = c.Next() // zString
  1644  	u, e1 := stringToNodeID(l)
  1645  	if e1 != nil || l.err {
  1646  		return e1
  1647  	}
  1648  	rr.NodeID = u
  1649  	return slurpRemainder(c)
  1650  }
  1651  
  1652  func (rr *L32) parse(c *zlexer, o string) *ParseError {
  1653  	l, _ := c.Next()
  1654  	i, e := strconv.ParseUint(l.token, 10, 16)
  1655  	if e != nil || l.err {
  1656  		return &ParseError{"", "bad L32 Preference", l}
  1657  	}
  1658  	rr.Preference = uint16(i)
  1659  	c.Next()        // zBlank
  1660  	l, _ = c.Next() // zString
  1661  	rr.Locator32 = net.ParseIP(l.token)
  1662  	if rr.Locator32 == nil || l.err {
  1663  		return &ParseError{"", "bad L32 Locator", l}
  1664  	}
  1665  	return slurpRemainder(c)
  1666  }
  1667  
  1668  func (rr *LP) parse(c *zlexer, o string) *ParseError {
  1669  	l, _ := c.Next()
  1670  	i, e := strconv.ParseUint(l.token, 10, 16)
  1671  	if e != nil || l.err {
  1672  		return &ParseError{"", "bad LP Preference", l}
  1673  	}
  1674  	rr.Preference = uint16(i)
  1675  
  1676  	c.Next()        // zBlank
  1677  	l, _ = c.Next() // zString
  1678  	rr.Fqdn = l.token
  1679  	name, nameOk := toAbsoluteName(l.token, o)
  1680  	if l.err || !nameOk {
  1681  		return &ParseError{"", "bad LP Fqdn", l}
  1682  	}
  1683  	rr.Fqdn = name
  1684  	return slurpRemainder(c)
  1685  }
  1686  
  1687  func (rr *L64) 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{"", "bad L64 Preference", l}
  1692  	}
  1693  	rr.Preference = uint16(i)
  1694  	c.Next()        // zBlank
  1695  	l, _ = c.Next() // zString
  1696  	u, e1 := stringToNodeID(l)
  1697  	if e1 != nil || l.err {
  1698  		return e1
  1699  	}
  1700  	rr.Locator64 = u
  1701  	return slurpRemainder(c)
  1702  }
  1703  
  1704  func (rr *UID) parse(c *zlexer, o string) *ParseError {
  1705  	l, _ := c.Next()
  1706  	i, e := strconv.ParseUint(l.token, 10, 32)
  1707  	if e != nil || l.err {
  1708  		return &ParseError{"", "bad UID Uid", l}
  1709  	}
  1710  	rr.Uid = uint32(i)
  1711  	return slurpRemainder(c)
  1712  }
  1713  
  1714  func (rr *GID) parse(c *zlexer, o string) *ParseError {
  1715  	l, _ := c.Next()
  1716  	i, e := strconv.ParseUint(l.token, 10, 32)
  1717  	if e != nil || l.err {
  1718  		return &ParseError{"", "bad GID Gid", l}
  1719  	}
  1720  	rr.Gid = uint32(i)
  1721  	return slurpRemainder(c)
  1722  }
  1723  
  1724  func (rr *UINFO) parse(c *zlexer, o string) *ParseError {
  1725  	s, e := endingToTxtSlice(c, "bad UINFO Uinfo")
  1726  	if e != nil {
  1727  		return e
  1728  	}
  1729  	if ln := len(s); ln == 0 {
  1730  		return nil
  1731  	}
  1732  	rr.Uinfo = s[0] // silently discard anything after the first character-string
  1733  	return nil
  1734  }
  1735  
  1736  func (rr *PX) parse(c *zlexer, o string) *ParseError {
  1737  	l, _ := c.Next()
  1738  	i, e := strconv.ParseUint(l.token, 10, 16)
  1739  	if e != nil || l.err {
  1740  		return &ParseError{"", "bad PX Preference", l}
  1741  	}
  1742  	rr.Preference = uint16(i)
  1743  
  1744  	c.Next()        // zBlank
  1745  	l, _ = c.Next() // zString
  1746  	rr.Map822 = l.token
  1747  	map822, map822Ok := toAbsoluteName(l.token, o)
  1748  	if l.err || !map822Ok {
  1749  		return &ParseError{"", "bad PX Map822", l}
  1750  	}
  1751  	rr.Map822 = map822
  1752  
  1753  	c.Next()        // zBlank
  1754  	l, _ = c.Next() // zString
  1755  	rr.Mapx400 = l.token
  1756  	mapx400, mapx400Ok := toAbsoluteName(l.token, o)
  1757  	if l.err || !mapx400Ok {
  1758  		return &ParseError{"", "bad PX Mapx400", l}
  1759  	}
  1760  	rr.Mapx400 = mapx400
  1761  	return slurpRemainder(c)
  1762  }
  1763  
  1764  func (rr *CAA) parse(c *zlexer, o string) *ParseError {
  1765  	l, _ := c.Next()
  1766  	i, e := strconv.ParseUint(l.token, 10, 8)
  1767  	if e != nil || l.err {
  1768  		return &ParseError{"", "bad CAA Flag", l}
  1769  	}
  1770  	rr.Flag = uint8(i)
  1771  
  1772  	c.Next()        // zBlank
  1773  	l, _ = c.Next() // zString
  1774  	if l.value != zString {
  1775  		return &ParseError{"", "bad CAA Tag", l}
  1776  	}
  1777  	rr.Tag = l.token
  1778  
  1779  	c.Next() // zBlank
  1780  	s, e1 := endingToTxtSlice(c, "bad CAA Value")
  1781  	if e1 != nil {
  1782  		return e1
  1783  	}
  1784  	if len(s) != 1 {
  1785  		return &ParseError{"", "bad CAA Value", l}
  1786  	}
  1787  	rr.Value = s[0]
  1788  	return nil
  1789  }
  1790  
  1791  func (rr *TKEY) parse(c *zlexer, o string) *ParseError {
  1792  	l, _ := c.Next()
  1793  
  1794  	// Algorithm
  1795  	if l.value != zString {
  1796  		return &ParseError{"", "bad TKEY algorithm", l}
  1797  	}
  1798  	rr.Algorithm = l.token
  1799  	c.Next() // zBlank
  1800  
  1801  	// Get the key length and key values
  1802  	l, _ = c.Next()
  1803  	i, e := strconv.ParseUint(l.token, 10, 8)
  1804  	if e != nil || l.err {
  1805  		return &ParseError{"", "bad TKEY key length", l}
  1806  	}
  1807  	rr.KeySize = uint16(i)
  1808  	c.Next() // zBlank
  1809  	l, _ = c.Next()
  1810  	if l.value != zString {
  1811  		return &ParseError{"", "bad TKEY key", l}
  1812  	}
  1813  	rr.Key = l.token
  1814  	c.Next() // zBlank
  1815  
  1816  	// Get the otherdata length and string data
  1817  	l, _ = c.Next()
  1818  	i, e1 := strconv.ParseUint(l.token, 10, 8)
  1819  	if e1 != nil || l.err {
  1820  		return &ParseError{"", "bad TKEY otherdata length", l}
  1821  	}
  1822  	rr.OtherLen = uint16(i)
  1823  	c.Next() // zBlank
  1824  	l, _ = c.Next()
  1825  	if l.value != zString {
  1826  		return &ParseError{"", "bad TKEY otherday", l}
  1827  	}
  1828  	rr.OtherData = l.token
  1829  	return nil
  1830  }
  1831  
  1832  func (rr *APL) parse(c *zlexer, o string) *ParseError {
  1833  	var prefixes []APLPrefix
  1834  
  1835  	for {
  1836  		l, _ := c.Next()
  1837  		if l.value == zNewline || l.value == zEOF {
  1838  			break
  1839  		}
  1840  		if l.value == zBlank && prefixes != nil {
  1841  			continue
  1842  		}
  1843  		if l.value != zString {
  1844  			return &ParseError{"", "unexpected APL field", l}
  1845  		}
  1846  
  1847  		// Expected format: [!]afi:address/prefix
  1848  
  1849  		colon := strings.IndexByte(l.token, ':')
  1850  		if colon == -1 {
  1851  			return &ParseError{"", "missing colon in APL field", l}
  1852  		}
  1853  
  1854  		family, cidr := l.token[:colon], l.token[colon+1:]
  1855  
  1856  		var negation bool
  1857  		if family != "" && family[0] == '!' {
  1858  			negation = true
  1859  			family = family[1:]
  1860  		}
  1861  
  1862  		afi, e := strconv.ParseUint(family, 10, 16)
  1863  		if e != nil {
  1864  			return &ParseError{"", "failed to parse APL family: " + e.Error(), l}
  1865  		}
  1866  		var addrLen int
  1867  		switch afi {
  1868  		case 1:
  1869  			addrLen = net.IPv4len
  1870  		case 2:
  1871  			addrLen = net.IPv6len
  1872  		default:
  1873  			return &ParseError{"", "unrecognized APL family", l}
  1874  		}
  1875  
  1876  		ip, subnet, e1 := net.ParseCIDR(cidr)
  1877  		if e1 != nil {
  1878  			return &ParseError{"", "failed to parse APL address: " + e1.Error(), l}
  1879  		}
  1880  		if !ip.Equal(subnet.IP) {
  1881  			return &ParseError{"", "extra bits in APL address", l}
  1882  		}
  1883  
  1884  		if len(subnet.IP) != addrLen {
  1885  			return &ParseError{"", "address mismatch with the APL family", l}
  1886  		}
  1887  
  1888  		prefixes = append(prefixes, APLPrefix{
  1889  			Negation: negation,
  1890  			Network:  *subnet,
  1891  		})
  1892  	}
  1893  
  1894  	rr.Prefixes = prefixes
  1895  	return nil
  1896  }
  1897  

View as plain text