What is dns-packet?
The dns-packet npm package is a library for encoding/decoding DNS packets. It supports both Node.js and the browser and can handle various DNS record types. It is useful for creating custom DNS servers, clients, or for manipulating DNS packets for analysis or testing.
What are dns-packet's main functionalities?
Encoding DNS packets
This feature allows you to encode a DNS packet into a buffer. The example code shows how to create a DNS query packet for the domain 'example.com'.
const dnsPacket = require('dns-packet');
const encodedPacket = dnsPacket.encode({
type: 'query',
id: 1,
flags: dnsPacket.RECURSION_DESIRED,
questions: [{
type: 'A',
name: 'example.com'
}]
});
Decoding DNS packets
This feature allows you to decode a DNS packet from a buffer. The example code demonstrates how to decode a buffer into a DNS packet object.
const dnsPacket = require('dns-packet');
const buffer = Buffer.from('...'); // a buffer containing a DNS packet
const decodedPacket = dnsPacket.decode(buffer);
Streaming DNS packet encoding/decoding
This feature allows you to encode and decode DNS packets in a streaming fashion, which is useful for handling DNS packets in a network stream. The example code creates a simple DNS server that responds to all queries with the IP address '127.0.0.1'.
const dnsPacket = require('dns-packet');
const net = require('net');
const server = net.createServer((socket) => {
socket.pipe(dnsPacket.streamDecode())
.on('data', (packet) => {
console.log('received packet:', packet);
const response = dnsPacket.streamEncode({
type: 'response',
id: packet.id,
questions: packet.questions,
answers: [{
type: 'A',
name: packet.questions[0].name,
data: '127.0.0.1'
}]
});
socket.write(response);
});
});
server.listen(53);
Other packages similar to dns-packet
native-dns-packet
This package is similar to dns-packet, offering low-level DNS packet encoding/decoding with a focus on Node.js. It is an alternative that might be used in scenarios where native Node.js Buffer handling is preferred.
dns2
dns2 is a more comprehensive DNS toolkit that includes packet encoding/decoding functionalities similar to dns-packet. It also provides higher-level DNS server and client implementations, making it a more feature-rich option.
node-dns
node-dns is another DNS library that provides similar packet manipulation capabilities. It differs from dns-packet by offering a full DNS resolver and server implementation, potentially making it a better choice for more complex DNS-related tasks.
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'
}
If you need another one, open an issue and we'll try to add it.
License
MIT