Implement GPOS record

This commit is contained in:
Miek Gieben 2013-10-13 13:01:33 +01:00
parent 961e137891
commit cc2c42cc91
5 changed files with 155 additions and 106 deletions

View File

@ -14,7 +14,6 @@
These are deprecated, or rarely used (or just a bitch to implement).
PX
GPOS
NIMLOC
ATMA
A6

107
msg.go
View File

@ -79,73 +79,74 @@ type Msg struct {
// Map of strings for each RR wire type.
var TypeToString = map[uint16]string{
TypeA: "A",
TypeAAAA: "AAAA",
TypeAFSDB: "AFSDB",
TypeANY: "ANY", // Meta RR
TypeATMA: "ATMA",
TypeAXFR: "AXFR", // Meta RR
TypeCAA: "CAA",
TypeCDS: "CDS",
TypeCERT: "CERT",
TypeCNAME: "CNAME",
TypeDHCID: "DHCID",
TypeDLV: "DLV",
TypeDNAME: "DNAME",
TypeDNSKEY: "DNSKEY",
TypeDS: "DS",
TypeEUI48: "EUI48",
TypeEUI64: "EUI64",
TypeGID: "GID",
TypeGPOS: "GPOS",
TypeHINFO: "HINFO",
TypeTLSA: "TLSA",
TypeHIP: "HIP",
TypeIPSECKEY: "IPSECKEY",
TypeISDN: "ISDN",
TypeIXFR: "IXFR", // Meta RR
TypeKX: "KX",
TypeL32: "L32",
TypeL64: "L64",
TypeLOC: "LOC",
TypeLP: "LP",
TypeMB: "MB",
TypeMG: "MG",
TypeRP: "RP",
TypeMD: "MD",
TypeMF: "MF",
TypeMG: "MG",
TypeMINFO: "MINFO",
TypeMR: "MR",
TypeMX: "MX",
TypeWKS: "WKS",
TypeNS: "NS",
TypeNULL: "NULL",
TypeNSAP: "NSAP",
TypeNSAPPTR: "NSAP-PTR",
TypeAFSDB: "AFSDB",
TypeX25: "X25",
TypeISDN: "ISDN",
TypePTR: "PTR",
TypeRT: "RT",
TypeSOA: "SOA",
TypeTXT: "TXT",
TypeSRV: "SRV",
TypeATMA: "ATMA",
TypeNAPTR: "NAPTR",
TypeKX: "KX",
TypeCERT: "CERT",
TypeDNAME: "DNAME",
TypeA: "A",
TypeAAAA: "AAAA",
TypeLOC: "LOC",
TypeOPT: "OPT",
TypeDS: "DS",
TypeDHCID: "DHCID",
TypeHIP: "HIP",
TypeNID: "NID",
TypeNINFO: "NINFO",
TypeRKEY: "RKEY",
TypeCDS: "CDS",
TypeCAA: "CAA",
TypeIPSECKEY: "IPSECKEY",
TypeSSHFP: "SSHFP",
TypeRRSIG: "RRSIG",
TypeNSEC: "NSEC",
TypeDNSKEY: "DNSKEY",
TypeNS: "NS",
TypeNSAP: "NSAP",
TypeNSAPPTR: "NSAP-PTR",
TypeNSEC3: "NSEC3",
TypeNSEC3PARAM: "NSEC3PARAM",
TypeTALINK: "TALINK",
TypeNSEC: "NSEC",
TypeNULL: "NULL",
TypeOPT: "OPT",
TypePTR: "PTR",
TypeRKEY: "RKEY",
TypeRP: "RP",
TypeRRSIG: "RRSIG",
TypeRT: "RT",
TypeSOA: "SOA",
TypeSPF: "SPF",
TypeNID: "NID",
TypeL32: "L32",
TypeL64: "L64",
TypeLP: "LP",
TypeUINFO: "UINFO",
TypeUID: "UID",
TypeGID: "GID",
TypeUNSPEC: "UNSPEC",
TypeEUI48: "EUI48",
TypeEUI64: "EUI64",
TypeTKEY: "TKEY", // Meta RR
TypeTSIG: "TSIG", // Meta RR
TypeAXFR: "AXFR", // Meta RR
TypeIXFR: "IXFR", // Meta RR
TypeANY: "ANY", // Meta RR
TypeURI: "URI",
TypeSRV: "SRV",
TypeSSHFP: "SSHFP",
TypeTA: "TA",
TypeDLV: "DLV",
TypeTALINK: "TALINK",
TypeTKEY: "TKEY", // Meta RR
TypeTLSA: "TLSA",
TypeTSIG: "TSIG", // Meta RR
TypeTXT: "TXT",
TypeUID: "UID",
TypeUINFO: "UINFO",
TypeUNSPEC: "UNSPEC",
TypeURI: "URI",
TypeWKS: "WKS",
TypeX25: "X25",
}
// Reverse, needed for string parsing.

View File

@ -591,11 +591,13 @@ func TestILNP(t *testing.T) {
}
}
func TestNSAP(t *testing.T) {
func TestNSAPGPOS(t *testing.T) {
dt := map[string]string{
"foo.bar.com. IN NSAP 21 47000580ffff000000321099991111222233334444": "foo.bar.com.\t3600\tIN\tNSAP\t21 47000580ffff000000321099991111222233334444",
"host.school.de IN NSAP 17 39276f3100111100002222333344449876": "host.school.de.\t3600\tIN\tNSAP\t17 39276f3100111100002222333344449876",
"444433332222111199990123000000ff. NSAP-PTR foo.bar.com.": "444433332222111199990123000000ff.\t3600\tIN\tNSAP-PTR\tfoo.bar.com.",
"host.school.de IN NSAP 17 39276f3100111100002222333344449876": "host.school.de.\t3600\tIN\tNSAP\t17 39276f3100111100002222333344449876",
"444433332222111199990123000000ff. NSAP-PTR foo.bar.com.": "444433332222111199990123000000ff.\t3600\tIN\tNSAP-PTR\tfoo.bar.com.",
"lillee. IN GPOS -32.6882 116.8652 10.0": "lillee.\t3600\tIN\tGPOS\t-32.6882 116.8652 10.0",
"hinault. IN GPOS -22.6882 116.8652 250.0": "hinault.\t3600\tIN\tGPOS\t-22.6882 116.8652 250.0",
}
for i, o := range dt {
rr, e := NewRR(i)

116
types.go
View File

@ -50,6 +50,7 @@ const (
TypeNSAPPTR uint16 = 23
TypeSIG uint16 = 24
TypeKEY uint16 = 25
TypeGPOS uint16 = 27
TypeAAAA uint16 = 28
TypeLOC uint16 = 29
TypeNXT uint16 = 30
@ -650,6 +651,22 @@ func (rr *AAAA) String() string {
return rr.Hdr.String() + rr.AAAA.String()
}
type GPOS struct {
Hdr RR_Header
Longitude string
Latitude string
Altitude string
}
func (rr *GPOS) Header() *RR_Header { return &rr.Hdr }
func (rr *GPOS) copy() RR { return &GPOS{*rr.Hdr.copyHeader(), rr.Longitude, rr.Latitude, rr.Altitude} }
func (rr *GPOS) len() int {
return rr.Hdr.len() + len(rr.Longitude) + len(rr.Latitude) + len(rr.Altitude) + 3
}
func (rr *GPOS) String() string {
return rr.Hdr.String() + rr.Longitude + " " + rr.Latitude + " " + rr.Altitude
}
type LOC struct {
Hdr RR_Header
Version uint8
@ -1525,63 +1542,64 @@ func euiToString(eui uint64, bits int) (hex string) {
// Map of constructors for each RR wire type.
var rr_mk = map[uint16]func() RR{
TypeCNAME: func() RR { return new(CNAME) },
TypeHINFO: func() RR { return new(HINFO) },
TypeNSAP: func() RR { return new(NSAP) },
TypeNSAPPTR: func() RR { return new(NSAPPTR) },
TypeMB: func() RR { return new(MB) },
TypeMG: func() RR { return new(MG) },
TypeMD: func() RR { return new(MD) },
TypeMF: func() RR { return new(MF) },
TypeMINFO: func() RR { return new(MINFO) },
TypeRP: func() RR { return new(RP) },
TypeAFSDB: func() RR { return new(AFSDB) },
TypeX25: func() RR { return new(X25) },
TypeMR: func() RR { return new(MR) },
TypeMX: func() RR { return new(MX) },
TypeRKEY: func() RR { return new(RKEY) },
TypeNINFO: func() RR { return new(NINFO) },
TypeNS: func() RR { return new(NS) },
TypePTR: func() RR { return new(PTR) },
TypeSOA: func() RR { return new(SOA) },
TypeRT: func() RR { return new(RT) },
TypeTXT: func() RR { return new(TXT) },
TypeSRV: func() RR { return new(SRV) },
TypeNAPTR: func() RR { return new(NAPTR) },
TypeDNAME: func() RR { return new(DNAME) },
TypeA: func() RR { return new(A) },
TypeWKS: func() RR { return new(WKS) },
TypeAAAA: func() RR { return new(AAAA) },
TypeLOC: func() RR { return new(LOC) },
TypeOPT: func() RR { return new(OPT) },
TypeDS: func() RR { return new(DS) },
TypeAFSDB: func() RR { return new(AFSDB) },
TypeCAA: func() RR { return new(CAA) },
TypeCDS: func() RR { return new(CDS) },
TypeCERT: func() RR { return new(CERT) },
TypeKX: func() RR { return new(KX) },
TypeSPF: func() RR { return new(SPF) },
TypeTALINK: func() RR { return new(TALINK) },
TypeSSHFP: func() RR { return new(SSHFP) },
TypeRRSIG: func() RR { return new(RRSIG) },
TypeNSEC: func() RR { return new(NSEC) },
TypeDNSKEY: func() RR { return new(DNSKEY) },
TypeNSEC3: func() RR { return new(NSEC3) },
TypeCNAME: func() RR { return new(CNAME) },
TypeDHCID: func() RR { return new(DHCID) },
TypeNSEC3PARAM: func() RR { return new(NSEC3PARAM) },
TypeTKEY: func() RR { return new(TKEY) },
TypeTSIG: func() RR { return new(TSIG) },
TypeURI: func() RR { return new(URI) },
TypeTA: func() RR { return new(TA) },
TypeDLV: func() RR { return new(DLV) },
TypeTLSA: func() RR { return new(TLSA) },
TypeHIP: func() RR { return new(HIP) },
TypeNID: func() RR { return new(NID) },
TypeL32: func() RR { return new(L32) },
TypeL64: func() RR { return new(L64) },
TypeLP: func() RR { return new(LP) },
TypeDNAME: func() RR { return new(DNAME) },
TypeDNSKEY: func() RR { return new(DNSKEY) },
TypeDS: func() RR { return new(DS) },
TypeEUI48: func() RR { return new(EUI48) },
TypeEUI64: func() RR { return new(EUI64) },
TypeCAA: func() RR { return new(CAA) },
TypeUID: func() RR { return new(UID) },
TypeGID: func() RR { return new(GID) },
TypeGPOS: func() RR { return new(GPOS) },
TypeHINFO: func() RR { return new(HINFO) },
TypeHIP: func() RR { return new(HIP) },
TypeKX: func() RR { return new(KX) },
TypeL32: func() RR { return new(L32) },
TypeL64: func() RR { return new(L64) },
TypeLOC: func() RR { return new(LOC) },
TypeLP: func() RR { return new(LP) },
TypeMB: func() RR { return new(MB) },
TypeMD: func() RR { return new(MD) },
TypeMF: func() RR { return new(MF) },
TypeMG: func() RR { return new(MG) },
TypeMINFO: func() RR { return new(MINFO) },
TypeMR: func() RR { return new(MR) },
TypeMX: func() RR { return new(MX) },
TypeNAPTR: func() RR { return new(NAPTR) },
TypeNID: func() RR { return new(NID) },
TypeNINFO: func() RR { return new(NINFO) },
TypeNS: func() RR { return new(NS) },
TypeNSAP: func() RR { return new(NSAP) },
TypeNSAPPTR: func() RR { return new(NSAPPTR) },
TypeNSEC3: func() RR { return new(NSEC3) },
TypeNSEC3PARAM: func() RR { return new(NSEC3PARAM) },
TypeNSEC: func() RR { return new(NSEC) },
TypeOPT: func() RR { return new(OPT) },
TypePTR: func() RR { return new(PTR) },
TypeRKEY: func() RR { return new(RKEY) },
TypeRP: func() RR { return new(RP) },
TypeRRSIG: func() RR { return new(RRSIG) },
TypeRT: func() RR { return new(RT) },
TypeSOA: func() RR { return new(SOA) },
TypeSPF: func() RR { return new(SPF) },
TypeSRV: func() RR { return new(SRV) },
TypeSSHFP: func() RR { return new(SSHFP) },
TypeTA: func() RR { return new(TA) },
TypeTALINK: func() RR { return new(TALINK) },
TypeTKEY: func() RR { return new(TKEY) },
TypeTLSA: func() RR { return new(TLSA) },
TypeTSIG: func() RR { return new(TSIG) },
TypeTXT: func() RR { return new(TXT) },
TypeUID: func() RR { return new(UID) },
TypeUINFO: func() RR { return new(UINFO) },
TypeURI: func() RR { return new(URI) },
TypeWKS: func() RR { return new(WKS) },
TypeX25: func() RR { return new(X25) },
}

View File

@ -125,6 +125,9 @@ func setRR(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
case TypeNSAPPTR:
r, e = setNSAPPTR(h, c, o, f)
goto Slurp
case TypeGPOS:
r, e = setGPOS(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.
@ -1573,6 +1576,32 @@ func setNSAP(h RR_Header, c chan lex, f string) (RR, *ParseError, string) {
return rr, nil, c1
}
func setGPOS(h RR_Header, c chan lex, f string) (RR, *ParseError) {
rr := new(GPOS)
rr.Hdr = h
l := <-c
if _, e := strconv.ParseFloat(l.token, 64); e != nil {
return nil, &ParseError{f, "bad GPOS Longitude", l}
} else {
rr.Longitude = l.token
}
<-c // _BLANK
l = <-c
if _, e := strconv.ParseFloat(l.token, 64); e != nil {
return nil, &ParseError{f, "bad GPOS Latitude", l}
} else {
rr.Latitude = l.token
}
<-c // _BLANK
l = <-c
if _, e := strconv.ParseFloat(l.token, 64); e != nil {
return nil, &ParseError{f, "bad GPOS Altitude", l}
} else {
rr.Altitude = l.token
}
return rr, nil
}
func setCDS(h RR_Header, c chan lex, f string) (RR, *ParseError, string) {
rr := new(CDS)
rr.Hdr = h