Add EUI48 (108) and EUI64 (109)

This is an implementation of
http://tools.ietf.org/html/draft-jabley-dnsext-eui48-eui64-rrtypes-02
This commit is contained in:
Miek Gieben 2013-04-15 17:34:21 +01:00
parent e1c501fcec
commit 4c7a8b4985
2 changed files with 97 additions and 5 deletions

View File

@ -72,6 +72,8 @@ const (
TypeL32 uint16 = 105
TypeL64 uint16 = 106
TypeLP uint16 = 107
TypeEUI48 uint16 = 108
TypeEUI64 uint16 = 109
TypeTKEY uint16 = 249
TypeTSIG uint16 = 250
@ -1049,7 +1051,7 @@ func (rr *NSEC3) String() string {
s += strconv.Itoa(int(rr.Hash)) +
" " + strconv.Itoa(int(rr.Flags)) +
" " + strconv.Itoa(int(rr.Iterations)) +
" " + saltString(rr.Salt) +
" " + saltToString(rr.Salt) +
" " + rr.NextDomain
for i := 0; i < len(rr.TypeBitMap); i++ {
if _, ok := TypeToString[rr.TypeBitMap[i]]; ok {
@ -1085,7 +1087,7 @@ func (rr *NSEC3PARAM) String() string {
s += strconv.Itoa(int(rr.Hash)) +
" " + strconv.Itoa(int(rr.Flags)) +
" " + strconv.Itoa(int(rr.Iterations)) +
" " + saltString(rr.Salt)
" " + saltToString(rr.Salt)
return s
}
@ -1373,6 +1375,40 @@ func (rr *LP) len() int {
return rr.Hdr.len() + 2 + len(rr.Fqdn) + 1
}
type EUI48 struct {
Hdr RR_Header
Address uint64 `dns:"uint48"`
}
func (rr *EUI48) Header() *RR_Header { return &rr.Hdr }
func (rr *EUI48) copy() RR { return &EUI48{*rr.Hdr.copyHeader(), rr.Address} }
func (rr *EUI48) String() string {
s := rr.Hdr.String() + euiToString(rr.Address, 48)
return s
}
func (rr *EUI48) len() int {
return rr.Hdr.len() + 8 // we need a whole uint64
}
type EUI64 struct {
Hdr RR_Header
Address uint64
}
func (rr *EUI64) Header() *RR_Header { return &rr.Hdr }
func (rr *EUI64) copy() RR { return &EUI64{*rr.Hdr.copyHeader(), rr.Address} }
func (rr *EUI64) String() string {
s := rr.Hdr.String() + euiToString(rr.Address, 64)
return s
}
func (rr *EUI64) len() int {
return rr.Hdr.len() + 8 // we need a whole uint64
}
// TimeToString translates the RRSIG's incep. and expir. times to the
// string representation used when printing the record.
// It takes serial arithmetic (RFC 1982) into account.
@ -1385,7 +1421,7 @@ func TimeToString(t uint32) string {
return ti.Format("20060102150405")
}
// StringToTime translates the RRSIG's incep. and expir. times from
// StringToTime translates the RRSIG's incep. and expir. times from
// string values like "20110403154150" to an 32 bit integer.
// It takes serial arithmetic (RFC 1982) into account.
func StringToTime(s string) (uint32, error) {
@ -1400,9 +1436,9 @@ func StringToTime(s string) (uint32, error) {
return uint32(t.Unix() - (mod * year68)), nil
}
// saltString converts a NSECX salt to uppercase and
// saltToString converts a NSECX salt to uppercase and
// returns "-" when it is empty
func saltString(s string) string {
func saltToString(s string) string {
if len(s) == 0 {
return "-"
}
@ -1426,6 +1462,20 @@ func cmToString(mantissa, exponent uint8) string {
panic("dns: not reached")
}
func euiToString(eui uint64, bits int) (hex string) {
switch bits {
case 64:
hex = fmt.Sprintf("%x", eui)
hex = hex[0:1] + "-" + hex[2:3] + "-" + hex[4:5] + "-" + hex[6:7] +
"-" + hex[8:9] + "-" + hex[10:11] + "-" + hex[12:13] + "-" + hex[14:15]
case 48:
hex = fmt.Sprintf("%x", eui) // >> 16?
hex = hex[0:1] + "-" + hex[2:3] + "-" + hex[4:5] + "-" + hex[6:7] +
"-" + hex[8:9] + "-" + hex[10:11]
}
return
}
// Map of constructors for each RR wire type.
var rr_mk = map[uint16]func() RR{
TypeCNAME: func() RR { return new(CNAME) },
@ -1479,4 +1529,6 @@ var rr_mk = map[uint16]func() RR{
TypeL32: func() RR { return new(L32) },
TypeL64: func() RR { return new(L64) },
TypeLP: func() RR { return new(LP) },
TypeEUI48: func() RR { return new(EUI48) },
TypeEUI64: func() RR { return new(EUI64) },
}

View File

@ -100,6 +100,12 @@ func setRR(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
case TypeNSEC3PARAM:
r, e = setNSEC3PARAM(h, c, f)
goto Slurp
case TypeEUI48:
r, e = setEUI48(h, c, f)
goto Slurp
case TypeEUI64:
r, e = setEUI64(h, c, f)
goto Slurp
// These types have a variable ending: either chunks of txt or chunks/base64 or hex.
// They need to search for the end of the RR themselves, hence they look for the ending
// newline. Thus there is no need to slurp the remainder, because there is none.
@ -1271,6 +1277,40 @@ func setNSEC3PARAM(h RR_Header, c chan lex, f string) (RR, *ParseError) {
return rr, nil
}
func setEUI48(h RR_Header, c chan lex, f string) (RR, *ParseError) {
rr := new(EUI48)
rr.Hdr = h
l := <-c
if len(l.token) != 17 {
return nil, &ParseError{f, "bad EUI48 Address", l}
}
if i, e := strconv.Atoi(l.token); e != nil {
return nil, &ParseError{f, "bad EUI48 Address", l}
} else {
rr.Address = uint64(i)
}
return nil, nil
}
func setEUI64(h RR_Header, c chan lex, f string) (RR, *ParseError) {
rr := new(EUI64)
rr.Hdr = h
l := <-c
if len(l.token) != 23 {
return nil, &ParseError{f, "bad EUI64 Address", l}
}
if i, e := strconv.Atoi(l.token); e != nil {
return nil, &ParseError{f, "bad EUI64 Address", l}
} else {
rr.Address = uint64(i)
}
return nil, nil
}
func setWKS(h RR_Header, c chan lex, f string) (RR, *ParseError, string) {
rr := new(WKS)
rr.Hdr = h