dns

package module
v0.0.0-...-0236e13 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 14, 2024 License: MIT Imports: 6 Imported by: 0

README

DNS

DNS is a hands on library for DNS message parsing and building in Golang for those who would like to control the details of DNS messages.

Prerequisites

This library is not a DNS server. You can build a DNS server with this library, but it is not handled by the library itself. This means that you need a basic knowledge of DNS to use this library, though examples will be provided.

Installation

Add import to your application:

import "github.com/cmol/dns"

Usage

// Read a DNS message query from a 'bytes.Buffer'
query, err = dns.ParseMessage(buffer)

// Make a reply struct to said message
reply = dns.ReplyTo(query)

// Add EDNS information to the message
reply.Additional = []dns.Record{*dns.DefaultOpt(1024)}

// Create output buffer and build message in the buffer
buf := new(bytes.Buffer)
err = reply.Build(buf, dns.NewDomains())

// Send out the message on an existing remote connection
n, err = connection.WriteToUDP(buf.Bytes(), remoteAddr)

Contributing

Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change.

New Resource Record parsers and builders are welcome, but

Please make sure to update tests as appropriate.

Supported Resource Record types

Current list of supported RR types, though I will add more as I use the library:

  • A
  • AAAA
  • CNAME
  • OPT

More types are welcome! Please add tests and references to the standard in the PR.

License

MIT

Documentation

Overview

Package dns provides a fine grained DNS message parsing and building library

Index

Constants

View Source
const (
	// OptRa describes if recursion is available
	OptRa = 0x80
	// OptRd describes if recursion is desired
	OptRd = 0x100
	// OptTc describes if the messages was truncated
	OptTc = 0x200
	// OptAa describes weither a response came from the authoritative server
	OptAa = 0x400
	// OptQr describes if the message is a query (0) or response (1)
	OptQr = 0x8000
)
View Source
const (
	// NamePointer indication byte
	NamePointer = 0xc0

	// PointerMask is the reverse of the indication byte for 16 bits
	PointerMask = 0x3fff
)
View Source
const CacheFlushBit = 0x8000

CacheFlushBit holds the bit for the mDNS cache flush instruction

View Source
const HdrLength = 12

HdrLength is the length of a DNS message header

View Source
const UnicastResponseBit = 0x8000

UnicastResponseBit holds the bit for the mDNS unicast response

Variables

View Source
var RRTypeStrings = map[Type]string{
	A:          "A",
	NS:         "NS",
	CNAME:      "CNAME",
	SOA:        "SOA",
	PTR:        "PTR",
	HINFO:      "HINFO",
	MX:         "MX",
	TXT:        "TXT",
	RP:         "RP",
	AFSDB:      "AFSDB",
	SIG:        "SIG",
	KEY:        "KEY",
	AAAA:       "AAAA",
	LOC:        "LOC",
	SRV:        "SRV",
	NAPTR:      "NAPTR",
	KX:         "KX",
	CERT:       "CERT",
	DNAME:      "DNAME",
	OPT:        "OPT",
	APL:        "APL",
	DS:         "DS",
	SSHFP:      "SSHFP",
	IPSECKEY:   "IPSECKEY",
	RRSIG:      "RRSIG",
	NSEC:       "NSEC",
	DNSKEY:     "DNSKEY",
	DHCID:      "DHCID",
	NSEC3:      "NSEC3",
	NSEC3PARAM: "NSEC3PARAM",
	TLSA:       "TLSA",
	SMIMEA:     "SMIMEA",
	HIP:        "HIP",
	CDS:        "CDS",
	CDNSKEY:    "CDNSKEY",
	OPENPGPKEY: "OPENPGPKEY",
	CSYNC:      "CSYNC",
	ZONEMD:     "ZONEMD",
	SVCB:       "SVCB",
	HTTPS:      "HTTPS",
	EUI48:      "EUI48",
	EUI64:      "EUI64",
	TKEY:       "TKEY",
	TSIG:       "TSIG",
	IXFR:       "IXFR",
	AXFR:       "AXFR",
	URI:        "URI",
	CAA:        "CAA",
	TA:         "TA",
	DLV:        "DLV",
}

RRTypeStrings holds name mapping for DNS type constants

Functions

func BuildName

func BuildName(name string, domains *Domains) string

BuildName returns a dns encoded name with pointers if possible

func ParseName

func ParseName(buf *bytes.Buffer, ptr int, domains *Domains) (string, error)

ParseName returns a name given a pointer

Types

type CName

type CName struct {
	Name string
	// contains filtered or unexported fields
}

CName implements interface RData

func (*CName) Build

func (n *CName) Build(buf *bytes.Buffer, domains *Domains) error

Build implements CNAME building for interface RData

func (*CName) Parse

func (n *CName) Parse(buf *bytes.Buffer, ptr int, domains *Domains) error

Parse implements CNAME parsing for interface RData

func (*CName) PreBuild

func (n *CName) PreBuild(_ *Record, domains *Domains) (int, error)

PreBuild implements CNAME pre building for interface RData

func (*CName) TransformName

func (*CName) TransformName(name string) string

TransformName satisfies the interface

type Class

type Class uint16

Class is just a uint16

const (
	// IN is the standard class
	IN Class = 1
)

type Domains

type Domains struct {
	// contains filtered or unexported fields
}

Domains holds maps for parsing and building CNAME pointers

func NewDomains

func NewDomains() *Domains

NewDomains returns a new map for parsing and building

func (*Domains) GetBuild

func (p *Domains) GetBuild(name string) (int, bool)

GetBuild returns af pointer for a given name

func (*Domains) GetParse

func (p *Domains) GetParse(ptr int) (string, bool)

GetParse returns a domain for a given pointer

func (*Domains) SetBuild

func (p *Domains) SetBuild(ptr int, name string)

SetBuild adds build pointers to the domain map

func (*Domains) SetParse

func (p *Domains) SetParse(ptr int, name string)

SetParse adds parse pointers to the domain map

type IPv4

type IPv4 struct {
	netip.Addr
}

IPv4 implements interface RData

func (*IPv4) Build

func (ip *IPv4) Build(buf *bytes.Buffer, _ *Domains) error

Build implements A building for interface RData

func (*IPv4) Parse

func (ip *IPv4) Parse(buf *bytes.Buffer, _ int, _ *Domains) error

Parse implements A parsing for interface RData

func (*IPv4) PreBuild

func (ip *IPv4) PreBuild(_ *Record, _ *Domains) (int, error)

PreBuild step, just returning record size

func (*IPv4) TransformName

func (*IPv4) TransformName(name string) string

TransformName satisfies the interface

type IPv6

type IPv6 struct {
	netip.Addr
}

IPv6 implements interface RData

func (*IPv6) Build

func (ip *IPv6) Build(buf *bytes.Buffer, _ *Domains) error

Build implements AAAA building for interface RData

func (*IPv6) Parse

func (ip *IPv6) Parse(buf *bytes.Buffer, _ int, _ *Domains) error

Parse implements AAAA parsing for interface RData

func (*IPv6) PreBuild

func (ip *IPv6) PreBuild(_ *Record, _ *Domains) (int, error)

PreBuild step, just returning record size

func (*IPv6) TransformName

func (*IPv6) TransformName(name string) string

TransformName satisfies the interface

type Message

type Message struct {
	ID     uint16
	QR     bool
	OPCode uint8
	AA     bool
	TC     bool
	RD     bool
	RA     bool
	RCode  uint8

	Questions   []Question
	Answers     []Record
	Nameservers []Record
	Additional  []Record
	// contains filtered or unexported fields
}

Message is the structure of an entire DNS message including subtypes

func ParseMessage

func ParseMessage(buf *bytes.Buffer) (*Message, error)

ParseMessage creates a new Message containing parsed DNS information from buf

func ReplyTo

func ReplyTo(other *Message) *Message

ReplyTo creates a reply Message from a Message

func (*Message) Build

func (m *Message) Build(buf *bytes.Buffer, domains *Domains) error

Build builds entire DNS message into buf

func (*Message) BuildHeader

func (m *Message) BuildHeader(buf *bytes.Buffer) error

BuildHeader writes DNS header to buf

func (*Message) ParseHeader

func (m *Message) ParseHeader(buf *bytes.Buffer) error

ParseHeader parses a `*bytes.Buffer`, looking for a DNS header, and returns an error based on the parsing success.

It should be noted that a successful parse does not mean that the header is valid.

type Opt

type Opt struct {
	UDPSize     uint16
	RCode       byte
	EDNSVersion byte
	DNSSec      bool
	Record      *Record
	Options     map[uint16][]byte
}

Opt implements interface for RDATA

func (*Opt) Build

func (o *Opt) Build(_ *bytes.Buffer, _ *Domains) error

Build implements OPT building for interface RData

func (*Opt) Parse

func (o *Opt) Parse(buf *bytes.Buffer, _ int, _ *Domains) error

Parse implements OPT parsing for interface RData

func (*Opt) PreBuild

func (o *Opt) PreBuild(r *Record, _ *Domains) (int, error)

PreBuild implements OPT pre building for interface RData

func (*Opt) TransformName

func (*Opt) TransformName(name string) string

TransformName satisfies the interface

type Ptr

type Ptr struct {
	Name string
	// contains filtered or unexported fields
}

Ptr implements interface RData

func (*Ptr) Build

func (n *Ptr) Build(buf *bytes.Buffer, domains *Domains) error

Build implements Ptr building for interface RData

func (*Ptr) Parse

func (n *Ptr) Parse(buf *bytes.Buffer, ptr int, domains *Domains) error

Parse implements Ptr parsing for interface RData

func (*Ptr) PreBuild

func (n *Ptr) PreBuild(_ *Record, domains *Domains) (int, error)

PreBuild implements Ptr pre building for interface RData

func (*Ptr) TransformName

func (*Ptr) TransformName(name string) string

TransformName satisfies the interface

type Question

type Question struct {
	Domain          string
	Type            Type
	Class           Class
	UnicastResponse bool
}

Question holds single dns questions

func ParseQuestion

func ParseQuestion(buf *bytes.Buffer, pointer int, domains *Domains) (Question, error)

ParseQuestion parses DNS question records

func (*Question) Build

func (q *Question) Build(buf *bytes.Buffer, domains *Domains) error

Build builds a DNS question record

type RData

type RData interface {
	Parse(*bytes.Buffer, int, *Domains) error
	Build(*bytes.Buffer, *Domains) error
	PreBuild(*Record, *Domains) (int, error)
	TransformName(string) string
}

RData interface for all record types

type Record

type Record struct {
	TTL        uint32
	Class      uint16
	Length     uint16
	Type       Type
	Name       string
	Data       RData
	CacheFlush bool
}

Record struct used by record specific types

func DefaultOpt

func DefaultOpt(size int) *Record

DefaultOpt returns a standard OPT record

func ParseRecord

func ParseRecord(buf *bytes.Buffer, ptr int, domains *Domains) (Record, error)

ParseRecord is the generic entry to parsing all records

func (*Record) Build

func (r *Record) Build(buf *bytes.Buffer, domains *Domains) error

Build is the generic entry to building all records

type Srv

type Srv struct {
	Priority uint16
	Weight   uint16
	Port     uint16
	Target   string

	NameBytes string
	// It seems like a lot of services does things like
	//   [identifier]._[service]._[proto].[name]
	// Support this scheme by adding data to this field if it there's more parts
	// to be parsed from the name
	Identifier string
	Service    string
	Proto      string
	Name       string
	// contains filtered or unexported fields
}

Srv implements interface RData

func (*Srv) Build

func (s *Srv) Build(buf *bytes.Buffer, domains *Domains) error

Build implements A building for interface RData

func (*Srv) Parse

func (s *Srv) Parse(buf *bytes.Buffer, ptr int, domains *Domains) error

Parse implements A parsing for interface RData

func (*Srv) PreBuild

func (s *Srv) PreBuild(_ *Record, domains *Domains) (int, error)

PreBuild step, building name and adding full record

func (*Srv) TransformName

func (s *Srv) TransformName(_ string) string

TransformName adds service/proto/name fields of server record

type Type

type Type uint16

Type is just a uint16

const (
	A          Type = 1
	NS         Type = 2
	CNAME      Type = 5
	SOA        Type = 6
	PTR        Type = 12
	HINFO      Type = 13
	MX         Type = 15
	TXT        Type = 16
	RP         Type = 17
	AFSDB      Type = 18
	SIG        Type = 24
	KEY        Type = 25
	AAAA       Type = 28
	LOC        Type = 29
	SRV        Type = 33
	NAPTR      Type = 35
	KX         Type = 36
	CERT       Type = 37
	DNAME      Type = 39
	OPT        Type = 41
	APL        Type = 42
	DS         Type = 43
	SSHFP      Type = 44
	IPSECKEY   Type = 45
	RRSIG      Type = 46
	NSEC       Type = 47
	DNSKEY     Type = 48
	DHCID      Type = 49
	NSEC3      Type = 50
	NSEC3PARAM Type = 51
	TLSA       Type = 52
	SMIMEA     Type = 53
	HIP        Type = 55
	CDS        Type = 59
	CDNSKEY    Type = 60
	OPENPGPKEY Type = 61
	CSYNC      Type = 62
	ZONEMD     Type = 63
	SVCB       Type = 64
	HTTPS      Type = 65
	EUI48      Type = 108
	EUI64      Type = 109
	TKEY       Type = 249
	TSIG       Type = 250
	IXFR       Type = 251
	AXFR       Type = 252
	URI        Type = 256
	CAA        Type = 257
	TA         Type = 32768
	DLV        Type = 32769
)

List of all DNS type constants

Directories

Path Synopsis
examples

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL