dns-packet
An abstract-encoding compliant module for encoding / decoding DNS packets.
Lifted out of multicast-dns as a separate module.
npm install dns-packet
UDP Usage
var packet = require('dns-packet')
var dgram = require('dgram')
var socket = dgram.createSocket('udp4')
var buf = packet.encode({
type: 'query',
id: 1,
flags: packet.RECURSION_DESIRED,
questions: [{
type: 'A',
class: 'IN',
name: 'google.com'
}]
})
socket.on('message', function (message) {
console.log(packet.decode(message))
})
socket.send(buf, 0, buf.length, 53, '8.8.8.8')
Also see the UDP example.
TCP Usage
While DNS has traditionally been used over a datagram transport, it is increasingly being carried over TCP for larger responses commonly including DNSSEC responses and TCP/TLS for privacy reasons.
See the TCP example.
API
var buf = packets.encode(packet, [buf], [offset])
Encodes a DNS packet into a buffer containing a UDP payload.
var packet = packets.decode(buf, [offset])
Decode a DNS packet from a buffer containing a UDP payload.
var buf = packets.streamEncode(packet, [buf], [offset])
Encodes a DNS packet into a buffer containing a TCP payload.
var packet = packets.streamDecode(buf, [offset])
Decode a DNS packet from a buffer containing a TCP payload.
var len = packets.encodingLength(packet)
Returns how many bytes are needed to encode the DNS packet
Packets
Packets look like this
{
type: 'query|response',
id: optionalIdNumber,
flags: optionalBitFlags,
questions: [...],
answers: [...],
additionals: [...],
authorities: [...]
}
The bit flags available are
packet.RECURSION_DESIRED
packet.RECURSION_AVAILABLE
packet.TRUNCATED_RESPONSE
packet.AUTHORITATIVE_ANSWER
packet.AUTHENTIC_DATA
packet.CHECKING_DISABLED
To use more than one flag bitwise-or them together
var flags = packet.RECURSION_DESIRED | packet.RECURSION_AVAILABLE
And to check for a flag use bitwise-and
var isRecursive = message.flags & packet.RECURSION_DESIRED
A question looks like this
{
type: 'A',
class: 'IN',
name: 'google.com'
}
And an answers, additional, or authority looks like this
{
type: 'A',
class: 'IN',
name: 'google.com',
ttl: optionalTimeToLiveInSeconds,
(record specific data, see below)
}
Currently the different available records are
A
{
data: 'IPv4 address'
}
AAAA
{
data: 'IPv6 address'
}
TXT
{
data: 'text' || Buffer || [ Buffer || 'text' ]
}
When encoding, scalar values are converted to an array and strings are converted to UTF-8 encoded Buffers. When decoding, the return value will always be an array of Buffer.
NS
{
data: nameServer
}
NULL
{
data: Buffer('any binary data')
}
SOA
{
data:
{
mname: domainName,
rname: mailbox,
serial: zoneSerial,
refresh: refreshInterval,
retry: retryInterval,
expire: expireInterval,
minimum: minimumTTL
}
}
SRV
{
data: {
port: servicePort,
target: serviceHostName,
priority: optionalServicePriority,
weight: optionalServiceWeight
}
}
HINFO
{
data: {
cpu: 'cpu info',
os: 'os info'
}
}
PTR
{
data: 'points.to.another.record'
}
CNAME
{
data: 'cname.to.another.record'
}
DNAME
{
data: 'dname.to.another.record'
}
CAA
{
flags: 128,
tag: 'issue|issuewild|iodef',
value: 'ca.example.net'
}
MX
{
preference: 10,
exchange: 'mail.example.net'
}
If you need another one, open an issue and we'll try to add it.
License
MIT