Add support for L32, NID, L64 and LP records

This commit is contained in:
Miek Gieben 2012-11-18 10:29:05 +01:00
parent a95de22bc3
commit 314a0eebcc
4 changed files with 111 additions and 27 deletions

View File

@ -637,25 +637,27 @@ func TestParseBackslash(t *testing.T) {
func TestILNP(t *testing.T) {
tests := []string{
"host1.example.com. IN NID 10 0014:4fff:ff20:ee64",
"host1.example.com. IN NID 20 0015:5fff:ff21:ee65",
"host2.example.com. IN NID 10 0016:6fff:ff22:ee66",
"host1.example.com. IN L32 10 10.1.02.0",
"host1.example.com. IN L32 20 10.1.04.0",
"host2.example.com. IN L32 10 10.1.08.0",
"host1.example.com. IN L64 10 2001:0DB8:1140:1000",
"host1.example.com. IN L64 20 2001:0DB8:2140:2000",
"host2.example.com. IN L64 10 2001:0DB8:4140:4000",
"host1.example.com. IN LP 10 l64-subnet1.example.com.",
"host1.example.com. IN LP 10 l64-subnet2.example.com.",
"host1.example.com. IN LP 20 l32-subnet1.example.com.",
"host1.example.com.\t3600\tIN\tNID\t10 0014:4fff:ff20:ee64",
"host1.example.com.\t3600\tIN\tNID\t20 0015:5fff:ff21:ee65",
"host2.example.com.\t3600\tIN\tNID\t10 0016:6fff:ff22:ee66",
"host1.example.com.\t3600\tIN\tL32\t10 10.1.2.0",
"host1.example.com.\t3600\tIN\tL32\t20 10.1.4.0",
"host2.example.com.\t3600\tIN\tL32\t10 10.1.8.0",
"host1.example.com.\t3600\tIN\tL64\t10 2001:0DB8:1140:1000",
"host1.example.com.\t3600\tIN\tL64\t20 2001:0DB8:2140:2000",
"host2.example.com.\t3600\tIN\tL64\t10 2001:0DB8:4140:4000",
"host1.example.com.\t3600\tIN\tLP\t10 l64-subnet1.example.com.",
"host1.example.com.\t3600\tIN\tLP\t10 l64-subnet2.example.com.",
"host1.example.com.\t3600\tIN\tLP\t20 l32-subnet1.example.com.",
}
for _, t1 := range tests {
r, e := NewRR(t1)
if e != nil {
t.Fatalf("An error occured: %s\n", e.Error())
} else {
t.Logf("%s\n", r.String())
if t1 != r.String() {
t.Fatalf("Strings should be equal %s %s", t1, r.String())
}
}
}
}

View File

@ -1388,7 +1388,7 @@ func (rr *RR_NID) Header() *RR_Header {
func (rr *RR_NID) String() string {
s := rr.Hdr.String() + strconv.Itoa(int(rr.Preference))
node := fmt.Sprintf("%0.16x", rr.NodeID)
s += node[0:3] + ":" + node[4:7] + ":" + node[8:11] + ":" + node[12:15]
s += " " + node[0:4] + ":" + node[4:8] + ":" + node[8:12] + ":" + node[12:16]
return s
}
@ -1411,7 +1411,8 @@ func (rr *RR_L32) Header() *RR_Header {
}
func (rr *RR_L32) String() string {
return rr.Hdr.String() + rr.Locator32.String()
return rr.Hdr.String() + strconv.Itoa(int(rr.Preference)) +
" " + rr.Locator32.String()
}
func (rr *RR_L32) Len() int {
@ -1435,7 +1436,7 @@ func (rr *RR_L64) Header() *RR_Header {
func (rr *RR_L64) String() string {
s := rr.Hdr.String() + strconv.Itoa(int(rr.Preference))
node := fmt.Sprintf("%0.16X", rr.Locator64)
s += node[0:3] + ":" + node[4:7] + ":" + node[8:11] + ":" + node[12:15]
s += " " + node[0:4] + ":" + node[4:8] + ":" + node[8:12] + ":" + node[12:16]
return s
}

View File

@ -826,3 +826,21 @@ func slurpRemainder(c chan lex, f string) *ParseError {
}
return nil
}
// Parse a 64 bit-like ipv6 address: "0014:4fff:ff20:ee64"
// Used for NID and L64 record.
func stringToNodeID(l lex) (uint64, *ParseError) {
if len(l.token) < 19 {
return 0, &ParseError{l.token, "bad NID/L64 NodeID/Locator64", l}
}
// There must be three colons at fixes postitions, if not its a parse error
if l.token[4] != ':' && l.token[9] != ':' && l.token[14] != ':' {
return 0, &ParseError{l.token, "bad NID/L64 NodeID/Locator64", l}
}
s := l.token[0:4] + l.token[5:9] + l.token[10:14] + l.token[15:19]
u, e := strconv.ParseUint(s, 16,64)
if e != nil {
return 0, &ParseError{l.token, "bad NID/L64 NodeID/Locator64", l}
}
return u, nil
}

View File

@ -82,14 +82,14 @@ func setRR(h RR_Header, c chan lex, o, f string) (RR, *ParseError) {
case TypeKX:
r, e = setKX(h, c, o, f)
goto Slurp
// case TypeNID:
// r, e := setNID(h, c, f)
case TypeNID:
r, e = setNID(h, c, f)
case TypeL32:
r, e = setL32(h, c, f)
// case TypeL64:
// r, e := setL64(h, c, f)
// case TypeLP:
// r, e := setLP(h, c, o, f)
case TypeL64:
r, e = setL64(h, c, f)
case TypeLP:
r, e = setLP(h, c, o, f)
// 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.
@ -392,7 +392,7 @@ func setMX(h RR_Header, c chan lex, o, f string) (RR, *ParseError) {
if i, e := strconv.Atoi(l.token); e != nil {
return nil, &ParseError{f, "bad MX Pref", l}
} else {
rr.Pref = uint16(i)
rr.Preference = uint16(i)
}
<-c // _BLANK
l = <-c // _STRING
@ -473,7 +473,7 @@ func setKX(h RR_Header, c chan lex, o, f string) (RR, *ParseError) {
if i, e := strconv.Atoi(l.token); e != nil {
return nil, &ParseError{f, "bad KX Pref", l}
} else {
rr.Pref = uint16(i)
rr.Preference = uint16(i)
}
<-c // _BLANK
l = <-c // _STRING
@ -660,7 +660,7 @@ func setNAPTR(h RR_Header, c chan lex, o, f string) (RR, *ParseError) {
if i, e := strconv.Atoi(l.token); e != nil {
return nil, &ParseError{f, "bad NAPTR Preference", l}
} else {
rr.Pref = uint16(i)
rr.Preference = uint16(i)
}
// Flags
<-c // _BLANK
@ -1093,7 +1093,7 @@ func setNSEC(h RR_Header, c chan lex, o, f string) (RR, *ParseError) {
rr.TypeBitMap = make([]uint16, 0)
var (
k uint16
k uint16
ok bool
)
l = <-c
@ -1738,7 +1738,23 @@ func setDHCID(h RR_Header, c chan lex, f string) (RR, *ParseError) {
}
func setNID(h RR_Header, c chan lex, f string) (RR, *ParseError) {
return nil, nil
rr := new(RR_NID)
rr.Hdr = h
l := <-c
if i, e := strconv.Atoi(l.token); e != nil {
return nil, &ParseError{f, "bad NID Preference", l}
} else {
rr.Preference = uint16(i)
}
<-c // _BLANK
l = <-c // _STRING
u, err := stringToNodeID(l)
if err != nil {
return nil, err
}
rr.NodeID = u
return rr, nil
}
func setL32(h RR_Header, c chan lex, f string) (RR, *ParseError) {
@ -1759,3 +1775,50 @@ func setL32(h RR_Header, c chan lex, f string) (RR, *ParseError) {
}
return rr, nil
}
func setLP(h RR_Header, c chan lex, o, f string) (RR, *ParseError) {
rr := new(RR_LP)
rr.Hdr = h
l := <-c
if i, e := strconv.Atoi(l.token); e != nil {
return nil, &ParseError{f, "bad LP Preference", l}
} else {
rr.Preference = uint16(i)
}
<-c // _BLANK
l = <-c // _STRING
rr.Fqdn = l.token
if l.token == "@" {
rr.Fqdn = o
return rr, nil
}
_, ld, ok := IsDomainName(l.token)
if !ok {
return nil, &ParseError{f, "bad LP Fqdn", l}
}
if rr.Fqdn[ld-1] != '.' {
rr.Fqdn = appendOrigin(rr.Fqdn, o)
}
return rr, nil
}
func setL64(h RR_Header, c chan lex, f string) (RR, *ParseError) {
rr := new(RR_L64)
rr.Hdr = h
l := <-c
if i, e := strconv.Atoi(l.token); e != nil {
return nil, &ParseError{f, "bad L64 Preference", l}
} else {
rr.Preference = uint16(i)
}
<-c // _BLANK
l = <-c // _STRING
u, err := stringToNodeID(l)
if err != nil {
return nil, err
}
rr.Locator64 = u
return rr, nil
}