package rr import ( "sort" "github.com/miekg/dns" ) // TypeInfo describes a record type for the web UI and CLI. type TypeInfo struct { Type string `json:"type"` Code uint16 `json:"code"` Common bool `json:"common"` Description string `json:"description"` Format string `json:"format,omitempty"` Example string `json:"example,omitempty"` } var described = []TypeInfo{ {Type: "A", Common: true, Description: "IPv4 address", Format: "", Example: "192.0.2.10"}, {Type: "AAAA", Common: true, Description: "IPv6 address", Format: "", Example: "2001:db8::10"}, {Type: "CNAME", Common: true, Description: "Alias for another name (no other records may exist at the same name)", Format: "", Example: "www.example.com."}, {Type: "MX", Common: true, Description: "Mail exchanger", Format: " ", Example: "10 mail.example.com."}, {Type: "TXT", Common: true, Description: "Text. Plain text is quoted and split into 255-byte strings automatically; start with a quote to give presentation format.", Format: " or \"string\" \"string\"", Example: "v=spf1 mx -all"}, {Type: "NS", Common: true, Description: "Name server for the zone (at the apex) or a delegation (below it)", Format: "", Example: "ns1.example.com."}, {Type: "PTR", Common: true, Description: "Reverse mapping (in in-addr.arpa / ip6.arpa zones)", Format: "", Example: "host.example.com."}, {Type: "SRV", Common: true, Description: "Service location (owner _service._proto.name)", Format: " ", Example: "0 5 5060 sip.example.com."}, {Type: "CAA", Common: true, Description: "Certification authority authorization", Format: " ", Example: "0 issue \"letsencrypt.org\""}, {Type: "HTTPS", Common: true, Description: "HTTPS service binding (RFC 9460)", Format: " [params...]", Example: "1 . alpn=\"h2,h3\""}, {Type: "SVCB", Description: "General service binding (RFC 9460)", Format: " [params...]", Example: "1 svc.example.com. alpn=\"h2\" port=8443"}, {Type: "SSHFP", Description: "SSH host key fingerprint", Format: " ", Example: "4 2 9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08"}, {Type: "TLSA", Description: "TLS certificate association, DANE (owner _port._proto.name)", Format: " ", Example: "3 1 1 0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"}, {Type: "DS", Description: "Delegation signer for a signed child zone (at a delegation point)", Format: " ", Example: "12345 13 2 0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"}, {Type: "DNAME", Description: "Redirects a whole subtree to another name", Format: "", Example: "other.example.net."}, {Type: "NAPTR", Description: "Naming authority pointer", Format: " \"\" \"\" \"\" ", Example: "100 10 \"u\" \"E2U+sip\" \"!^.*$!sip:info@example.com!\" ."}, {Type: "LOC", Description: "Geographical location", Format: " m [size [hp [vp]]]", Example: "52 22 23.000 N 4 53 32.000 E -2.00m 0.00m 10000m 10m"}, {Type: "HINFO", Description: "Host information", Format: "\"\" \"\"", Example: "\"PC\" \"Linux\""}, {Type: "RP", Description: "Responsible person", Format: " ", Example: "admin.example.com. ."}, {Type: "URI", Description: "Uniform resource identifier", Format: " \"\"", Example: "10 1 \"https://example.com/\""}, {Type: "OPENPGPKEY", Description: "OpenPGP public key (DANE)", Format: ""}, {Type: "SMIMEA", Description: "S/MIME certificate association", Format: " "}, {Type: "CERT", Description: "Certificate", Format: " "}, {Type: "DHCID", Description: "DHCP identifier", Format: ""}, {Type: "AFSDB", Description: "AFS database location", Format: " ", Example: "1 afs.example.com."}, {Type: "APL", Description: "Address prefix list", Format: "[!]:/ ...", Example: "1:192.168.32.0/21"}, {Type: "IPSECKEY", Description: "IPsec key", Format: " "}, {Type: "KX", Description: "Key exchanger", Format: " ", Example: "10 kx.example.com."}, {Type: "KEY", Description: "Public key (SIG(0) and other legacy uses)", Format: " "}, {Type: "SPF", Description: "Deprecated SPF record type; publish SPF policies as TXT instead", Format: "\"v=spf1 ...\""}, {Type: "CSYNC", Description: "Child-to-parent synchronization", Format: " ", Example: "66 3 A NS AAAA"}, {Type: "EUI48", Description: "48-bit MAC address", Format: "xx-xx-xx-xx-xx-xx", Example: "00-00-5e-00-53-2a"}, {Type: "EUI64", Description: "64-bit EUI address", Format: "xx-xx-xx-xx-xx-xx-xx-xx", Example: "00-00-5e-ef-10-00-00-2a"}, {Type: "RESINFO", Description: "Resolver information (RFC 9606)", Format: "key=value ...", Example: "qnamemin exterr=15,16,17"}, } // Types returns information about every record type that can be managed, // common types first. func Types() []TypeInfo { seen := map[string]bool{} var out []TypeInfo for _, t := range described { code, ok := dns.StringToType[t.Type] if !ok { continue } t.Code = code out = append(out, t) seen[t.Type] = true } var rest []TypeInfo for code, name := range dns.TypeToString { if seen[name] { continue } if _, ok := dns.TypeToRR[code]; !ok { continue } if _, bad := forbidden[code]; bad { continue } rest = append(rest, TypeInfo{Type: name, Code: code, Description: name + " record (zone file format)"}) } sort.Slice(rest, func(i, j int) bool { return rest[i].Type < rest[j].Type }) return append(out, rest...) }