UNPKG

over-the-wire

Version:

Network inspection library for Node

143 lines (122 loc) 3.08 kB
const { compile } = require('struct-compile'); const { OsiModelLayers } = require('./osi'); const { DNSRecordType, DNSRecordClass } = require('./enums'); const mixins = require('./mixins'); const { DNSQuery, DNSAnswer, DNSAuthority, DNSAdditional } = require('./DNSRecord'); const { DNSHeader } = compile(` //@NE struct DNSHeader { /** Transaction ID */ uint16_t id; /** Flags */ uint16_t flags; /** Number of questions */ uint16_t qdcount; /** Number of answer RRs */ uint16_t ancount; /** Number of authority RRs */ uint16_t nscount; /** Number of additional RRs */ uint16_t arcount; }; `); const { length: baseLength } = DNSHeader.prototype.config; /** * DNS protocol layer * @class * @property {number} src - Source DNS port. * @property {number} dst - Destination DNS port. * @property {number} totalLength - This field specifies the length in bytes of the DNS datagram. * @property {number} checksum - The 16-bit checksum field is used for error-checking of the header and data. * @implements {Layer} */ class DNS extends DNSHeader { name = 'DNS'; constructor(data = {}, opts = {}) { super(data); mixins.ctor(this, data, opts); this.length = opts.allocated ?? this.totalLength * 4; } /** * Whether this is a DNS query * @type {boolean} */ get isQuery() { return !(this.flags & 0x8000); } /** * Whether this is a DNS response * @type {boolean} */ get isResponse() { return !!(this.flags & 0x8000); } /** * DNS operation code * @type {number} */ get opcode() { return (this.flags >> 11) & 0xF; } /** * Whether this is an authoritative answer * @type {boolean} */ get authoritativeAnswer() { return !!(this.flags & 0x0400); } /** * Whether this is a truncated message * @type {boolean} */ get truncation() { return !!(this.flags & 0x0200); } /** * Whether recursion is desired * @type {boolean} */ get recursionDesired() { return !!(this.flags & 0x0100); } /** * Whether recursion is available * @type {boolean} */ get recursionAvailable() { return !!(this.flags & 0x0080); } /** * DNS response code * @type {number} */ get responseCode() { return this.flags & 0xF; } static toAlloc = (data) => baseLength; static osi = OsiModelLayers.Application; osi = OsiModelLayers.Application; /** * Retrieves all fields of the DNS layer. * @returns {Object} The DNS layer fields as an object. */ toObject() { return { ...super.toObject(), queries: this.queries, answers: this.answers, authorities: this.authorities, additionals: this.additionals, }; } defaults(obj = {}, layers) { if (!obj.totalLength) { this.totalLength = this.length / 4; } } nextProto(layers) { return new layers.Payload(this._buf.subarray(this.length)); } } mixins.withOptions(DNS.prototype, { baseLength, skipTypes: [0x1, 0x0], lengthIsTotal: true }); module.exports = { DNS };