rawdns

package module
v0.0.0-...-ad17d4d Latest Latest
Warning

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

Go to latest
Published: Feb 27, 2021 License: MIT Imports: 4 Imported by: 0

README

rawdns

DNS messages (un)marshaller

Overview

This project is forked from cirocosta/rawdns and has been modified to make it more suitable for constructing and parsing the UDP packet of DNS.

For complete DNS functionality, see miekg/dns.

Example

package main

import (
	"github.com/0x2E/rawdns"
	"net"
)

func main() {
	// create socket
	conn, _ := net.Dial("udp", "8.8.8.8:53")
	defer conn.Close()

	// construct DNS packet content
	payload, _ := rawdns.Marshal(33, 1, "github.com", rawdns.QTypeA)

	// send UDP packet
	_, _ = conn.Write(payload)

	// receive UDP packet
	buf := make([]byte, 0, 1024)
	n, _ := conn.Read(buf)

	// parse
	resp, _ := rawdns.Unmarshal(buf[:n])
}

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Marshal

func Marshal(id uint16, rd byte, addr string, qtype QType) ([]byte, error)

Marshal return the DNS content can be used in UDP packet

func UnmarshalCompressedName

func UnmarshalCompressedName(msg []byte, c *CompressedName) (n int, err error)

UnmarshalCompressedName takes care of populating a CompressedName struct with information gathered from a compressed domain name buffer.

		msg[0]			msg[1]
	_____________________ ||______________________
     0  1  2  3  4  5  6  7  0  1  2  3  4  5  6  7
   +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
   | 1  1|                OFFSET                   |
   +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+

func UnmarshalHeader

func UnmarshalHeader(msg []byte, h *Header) (n int, err error)

func UnmarshalMessage

func UnmarshalMessage(msg []byte, m *Message) (err error)

func UnmarshalQuestion

func UnmarshalQuestion(msg []byte, q *Question) (n int, err error)
  1. pick a number --> indicates how many bytes we can read ahead --> if ZERO: then we know it comes a QTYPE and a QCLASS

2.

func UnmarshalRR

func UnmarshalRR(msg []byte, r *RR) (n int, err error)

Types

type CompressedName

type CompressedName struct {
	Offset    uint16
	IsPointer bool
}

Compression format expansion is necessary because programs are free to avoid using pointers in the message they generate but all of the consumers are required to understand arriving messages that contain pointers.

first to bits set to 1: pointer
first to bits set to 0: label
01 and 10 are reserved for future implementations.

func (CompressedName) ExpandCompressedName

func (c CompressedName) ExpandCompressedName(msg []byte) (name string, err error)

func (CompressedName) Marshal

func (c CompressedName) Marshal() (res []byte, err error)
type Header struct {

	// ID is an arbitrary 16bit request identifier that is
	// forwarded back in the response so that we can match them up.
	ID uint16

	// QR is an 1bit flag specifying whether this message is a query (0)
	// of a response (1)
	// 1bit
	QR byte

	// Opcode is a 4bit field that specifies the query type.
	// Possible values are:
	// 0		- standard query		(QUERY)
	// 1		- inverse query			(IQUERY)
	// 2		- server status request		(STATUS)
	// 3 to 15	- reserved for future use
	Opcode Opcode

	// AA indicates whether this is an (A)nswer from an (A)uthoritative
	// server.
	// Valid in responses only.
	// 1bit.
	AA byte

	// TC indicates whether the message was (T)run(C)ated due to the length
	// being grater than the permitted on the transmission channel.
	// 1bit.
	TC byte

	// RD indicates whether (R)ecursion is (D)esired or not.
	// 1bit.
	RD byte

	// RA indidicates whether (R)ecursion is (A)vailable or not.
	// 1bit.
	RA byte

	// Z is reserved for future use
	Z byte

	// RCODE contains the (R)esponse (CODE) - it's a 4bit field that is
	// set as part of responses.
	RCODE byte

	// QDCOUNT specifies the number of entries in the question section
	QDCOUNT uint16

	// ANCOUNT specifies the number of resource records (RR) in the answer
	// section
	ANCOUNT uint16

	// NSCOUNT specifies the number of name server resource records in the
	// authority section
	NSCOUNT uint16

	// ARCOUNT specifies the number of resource records in the additional
	// records section
	ARCOUNT uint16
}

Header encapsulates the construct of the header part of the DNS query message. It follows the conventions stated at RFC1035 section 4.1.1.

The header contains the following fields:

				0  1  2  3  4  5  6  7
     0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F
   +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
   |                      ID                       |
   +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
   |QR|   Opcode  |AA|TC|RD|RA|   Z    |   RCODE   |
   +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
   |                    QDCOUNT                    |
   +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
   |                    ANCOUNT                    |
   +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
   |                    NSCOUNT                    |
   +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
   |                    ARCOUNT                    |
   +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+

func (Header) Marshal

func (h Header) Marshal() (res []byte, err error)

type Message

type Message struct {

	// Header is always present. It includes fields
	// that specify which of the remaining sections
	// are present, and also specifies whether the
	// message is a query or a response, a standard
	// query of some other opcode etc
	Header

	// Question carries the "question" of the query,
	// defining parameters that determines what's
	// being asked.
	Questions []*Question

	// Answers encapsulates the resource records
	// retrieved when receiving answers from the
	// server queried.
	Answers []*RR
}

Message represents a DNS message that is sent via a transport.

func Unmarshal

func Unmarshal(raw []byte) (*Message, error)

Unmarshal return the parsed DNS response in UDP packet

func (Message) Marshal

func (m Message) Marshal() (res []byte, err error)

type Opcode

type Opcode byte

Opcode denotes a 4bit field that specified the query type.

const (
	OpcodeQuery Opcode = iota
	OpcodeIquery
	OpcodeStatus
)

type QClass

type QClass uint16
const (
	QClassUnknown QClass = iota

	// Internet
	QClassIN

	QClassCS
	QClassCH
	QClassHS

	// Any class
	QClassWildcard QClass = 255
)

type QType

type QType uint16
const (
	QTypeUnknown QType = iota

	// Host address
	QTypeA

	// Authoritative name server
	QTypeNS

	QTypeMD
	QTypeMF

	// Canonical name for an alias
	QTypeCNAME

	// Marks the start of a zone of authority
	QTypeSOA

	QTypeMB
	QTypeMG
	QTypeMR
	QTypeNULL
	QTypeWKS

	// Domain name pointer
	QTypePTR
	QTypeHINFO
	QTypeMINFO

	// Mail exchange
	QTypeMX
	QTypeTXT
	QTypeAXFR  QType = 252
	QTypeMAILB QType = 253
	QTypeMAILA QType = 254

	// All records
	QTypeWildcard QType = 255
)

type Question

type Question struct {
	// QNAME refers to the domain name to be resolved in the query.
	// It's represented as a sequence of labels where each label
	// consists
	QNAME string

	// QTYPE specifies the type of the query to perform.
	QTYPE QType

	// QCLASS
	QCLASS QClass
}
                              1  1  1  1  1  1
0  1  2  3  4  5  6  7  8  9  0  1  2  3  4  5

+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | | / QNAME / / / +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | QTYPE | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | QCLASS | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+

func (Question) Marshal

func (q Question) Marshal() (res []byte, err error)

type RCODE

type RCODE byte

RCODE denotes a 4bit field that specifies the response code for a query.

const (
	RCODENoError RCODE = iota
	RCODEFormatError
	RCODEServerFailure
	RCODENameError
	RCODENotImplemented
	RCODERefused
)

type RR

type RR struct {

	// NAME is the Domain name to which this resource record pertains.
	// It might either come in the compressed format or not, depending
	// on the server.
	// Typically this should come compressed (indicated by the first two
	// bits).
	NAME string

	// TYPE is the type of the RR. It specifies the meaning of the
	// data that RDATA contains.
	TYPE QType

	// CLASS identifies the class of the data holded on RDATA.
	CLASS QClass

	// TTL indicates the time interval in seconds that the resource
	// recorded may be cached before it should be discarded.
	TTL uint32

	// RDLENGTH specifies the length in octets of the RDATA field.
	// ps.: if there's a pointer in the RDATA, this length
	// will not count the final result (expanded), but the
	// actual amount in transfer.
	RDLENGTH uint16

	// RDATA is the generic data from the record.
	// The format of the information contained here varies
	// according to the tupple {TYPE, CLASS} of the RR.
	RDATA []byte
}

RR represents a resource record.

                                1  1  1  1  1  1
  0  1  2  3  4  5  6  7  8  9  0  1  2  3  4  5
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|                      NAME                     |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|                      TYPE                     |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|                     CLASS                     |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|                      TTL                      |
|                                               |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|                   RDLENGTH                    |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--|
/                     RDATA                     /
/                                               /
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+

func (*RR) Marshal

func (r *RR) Marshal() (res []byte, err error)

TODO in order to perform the proper marshalling, we'd need

to have the full message to properly compress the name,
unless we don't compress it at all.

Jump to

Keyboard shortcuts

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