DNS packet structure handling for questions, answers, authorities, and additional sections with proper flag management and metadata.
Complete DNS packet object with all sections and metadata.
// Complete DNS packet structure
interface DNSPacket {
type: 'query' | 'response'; // Packet type
id?: number; // Transaction ID (0-65535)
flags?: number; // DNS flags bitfield
questions?: Question[]; // Question section
answers?: Answer[]; // Answer section
authorities?: Answer[]; // Authority section
additionals?: Answer[]; // Additional section
}
// Question structure
interface Question {
type: string; // DNS record type ('A', 'AAAA', 'MX', etc.)
class?: string; // DNS class (default: 'IN')
name: string; // Domain name to query
}
// Answer/Authority/Additional structure
interface Answer {
type: string; // DNS record type
class?: string; // DNS class (default: 'IN')
name: string; // Domain name
ttl?: number; // Time to live in seconds
// Record-specific data properties
}Bitfield constants for DNS packet flags exported from the main module.
const dnsPacket = require('dns-packet');
// DNS flag constants
const AUTHORITATIVE_ANSWER = dnsPacket.AUTHORITATIVE_ANSWER; // 1 << 10 (0x0400)
const TRUNCATED_RESPONSE = dnsPacket.TRUNCATED_RESPONSE; // 1 << 9 (0x0200)
const RECURSION_DESIRED = dnsPacket.RECURSION_DESIRED; // 1 << 8 (0x0100)
const RECURSION_AVAILABLE = dnsPacket.RECURSION_AVAILABLE; // 1 << 7 (0x0080)
const AUTHENTIC_DATA = dnsPacket.AUTHENTIC_DATA; // 1 << 5 (0x0020)
const CHECKING_DISABLED = dnsPacket.CHECKING_DISABLED; // 1 << 4 (0x0010)
const DNSSEC_OK = dnsPacket.DNSSEC_OK; // 1 << 15 (0x8000)Additional Flag Details from Decoded Headers:
When decoding DNS headers, additional flag properties are available:
// Extended flag properties in decoded headers
interface DecodedHeader {
id: number;
type: 'query' | 'response';
flags: number; // Raw flags value
flag_qr: boolean; // Query/Response flag
opcode: string; // Operation code name
flag_aa: boolean; // Authoritative Answer
flag_tc: boolean; // Truncated Response
flag_rd: boolean; // Recursion Desired
flag_ra: boolean; // Recursion Available
flag_z: boolean; // Zero flag (reserved)
flag_ad: boolean; // Authentic Data
flag_cd: boolean; // Checking Disabled
rcode: string; // Response code name
questions: Array; // Question section array
answers: Array; // Answer section array
authorities: Array; // Authority section array
additionals: Array; // Additional section array
}Usage Examples:
const dnsPacket = require('dns-packet');
// Single flag
const queryPacket = {
type: 'query',
flags: dnsPacket.RECURSION_DESIRED,
questions: [{ type: 'A', name: 'example.com' }]
};
// Multiple flags using bitwise OR
const flags = dnsPacket.RECURSION_DESIRED | dnsPacket.DNSSEC_OK;
const secureQuery = {
type: 'query',
flags: flags,
questions: [{ type: 'A', name: 'example.com' }]
};
// Check for flags using bitwise AND
const hasRecursion = packet.flags & dnsPacket.RECURSION_DESIRED;
const isAuthoritative = packet.flags & dnsPacket.AUTHORITATIVE_ANSWER;Handling for DNS question section.
const { question } = require('dns-packet');
// Question encoding/decoding
question.encode(q, buf, offset);
question.decode(buf, offset);
question.encodingLength(q);
// Question structure
interface Question {
type: string; // Record type ('A', 'AAAA', 'MX', etc.)
class?: string; // DNS class (defaults to 'IN')
name: string; // Domain name to query
}Example:
const q = {
type: 'A',
class: 'IN', // Optional, defaults to 'IN'
name: 'example.com'
};
const encodedQuestion = question.encode(q);Handling for DNS answer, authority, and additional sections.
const { answer } = require('dns-packet');
// Answer encoding/decoding (also used for authorities and additionals)
answer.encode(a, buf, offset);
answer.decode(buf, offset);
answer.encodingLength(a);
// Answer structure (same for authorities and additionals)
interface Answer {
type: string; // Record type
class?: string; // DNS class (defaults to 'IN')
name: string; // Domain name
ttl?: number; // Time to live in seconds
// Additional properties based on record type
}Examples:
// A record answer
const aRecord = {
type: 'A',
name: 'example.com',
ttl: 300,
data: '192.168.1.1'
};
// MX record answer
const mxRecord = {
type: 'MX',
name: 'example.com',
ttl: 3600,
preference: 10,
exchange: 'mail.example.com'
};
// TXT record answer
const txtRecord = {
type: 'TXT',
name: 'example.com',
ttl: 300,
data: ['v=spf1 include:_spf.google.com ~all']
};Domain name encoding and decoding with compression support.
const { name } = require('dns-packet');
// Name encoding/decoding
name.encode(str, buf, offset, options);
name.decode(buf, offset, options);
name.encodingLength(str, options);
// Options for name encoding/decoding
interface NameOptions {
mail?: boolean; // Handle mail address format (@ as .)
}Usage Examples:
// Standard domain name
const domain = 'example.com';
const encoded = name.encode(domain);
const decoded = name.decode(encoded, 0);
// Mail address format (for SOA RNAME field)
const mailAddr = 'admin@example.com';
const encodedMail = name.encode('admin.example.com', buf, offset, { mail: true });Common packet validation patterns and error handling.
Query Packet:
const queryPacket = {
type: 'query',
id: Math.floor(Math.random() * 65536),
flags: dnsPacket.RECURSION_DESIRED,
questions: [{
type: 'A',
name: 'example.com'
}]
};Response Packet:
const responsePacket = {
type: 'response',
id: 1234, // Must match query ID
flags: dnsPacket.RECURSION_AVAILABLE | dnsPacket.AUTHORITATIVE_ANSWER,
questions: [/* original questions */],
answers: [{
type: 'A',
name: 'example.com',
ttl: 300,
data: '192.168.1.1'
}]
};Common error conditions and validation:
try {
const packet = dnsPacket.decode(buffer);
// Validate packet structure
if (!packet.questions || packet.questions.length === 0) {
throw new Error('No questions in packet');
}
// Check for truncation
if (packet.flags & dnsPacket.TRUNCATED_RESPONSE) {
console.warn('Response was truncated, consider using TCP');
}
} catch (error) {
if (error.message.includes('buffer overflow')) {
console.error('Malformed DNS packet');
} else if (error.message.includes('name too long')) {
console.error('Domain name exceeds maximum length');
} else {
console.error('DNS parsing error:', error.message);
}
}All packet structure functions track bytes consumed/produced:
const encoded = question.encode(q);
console.log('Question bytes:', question.encode.bytes);
const decoded = answer.decode(buf, offset);
console.log('Answer bytes consumed:', answer.decode.bytes);