Have ideas to improve npm?Join in the discussion! ¬Ľ

    dns-packet
    DefinitelyTyped icon, indicating that this package has TypeScript declarations provided by the separate @types/dns-packet package

    5.2.1¬†‚Äʬ†Public¬†‚Äʬ†Published

    dns-packet

    Coverage Status

    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

    const dnsPacket = require('dns-packet')
    const dgram = require('dgram')
     
    const socket = dgram.createSocket('udp4')
     
    const buf = dnsPacket.encode({
      type: 'query',
      id: 1,
      flags: dnsPacket.RECURSION_DESIRED,
      questions: [{
        type: 'A',
        name: 'google.com'
      }]
    })
     
    socket.on('message', message => {
      console.log(dnsPacket.decode(message)) // prints out a response from google dns
    })
     
    socket.send(buf, 0, buf.length, 53, '8.8.8.8')

    Also see the UDP example.

    TCP, TLS, HTTPS

    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 TLS or HTTPS for enhanced security. See below examples on how to use dns-packet to wrap DNS packets in these protocols:

    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', // or SRV, AAAA, etc
      class: 'IN', // one of IN, CS, CH, HS, ANY. Default: IN
      name: 'google.com' // which record are you looking for
    }

    And an answer, additional, or authority looks like this

    {
      type: 'A', // or SRV, AAAA, etc
      class: 'IN', // one of IN, CS, CH, HS
      name: 'google.com', // which name is this record for
      ttl: optionalTimeToLiveInSeconds,
      (record specific data, see below)
    }

    Supported record types

    A

    {
      data: 'IPv4 address' // fx 127.0.0.1
    }

    AAAA

    {
      data: 'IPv6 address' // fx fe80::1
    }

    CAA

    {
      flags: 128, // octet
      tag: 'issue|issuewild|iodef',
      value: 'ca.example.net',
      issuerCritical: false
    }

    CNAME

    {
      data: 'cname.to.another.record'
    }

    DNAME

    {
      data: 'dname.to.another.record'
    }

    DNSKEY

    {
      flags: 257, // 16 bits
      algorithm: 1, // octet
      key: Buffer
    }

    DS

    {
      keyTag: 12345,
      algorithm: 8,
      digestType: 1,
      digest: Buffer
    }

    HINFO

    {
      data: {
        cpu: 'cpu info',
        os: 'os info'
      }
    }

    MX

    {
      preference: 10,
      exchange: 'mail.example.net'
    }

    NS

    {
      data: nameServer
    }

    NSEC

    {
      nextDomain: 'a.domain',
      rrtypes: ['A', 'TXT', 'RRSIG']
    }

    NSEC3

    {
      algorithm: 1,
      flags: 0,
      iterations: 2,
      salt: Buffer,
      nextDomain: Buffer, // Hashed per RFC5155
      rrtypes: ['A', 'TXT', 'RRSIG']
    }

    NULL

    {
      data: Buffer('any binary data')
    }

    OPT

    EDNS0 options.

    {
      type: 'OPT',
      name: '.',
      udpPayloadSize: 4096,
      flags: packet.DNSSEC_OK,
      options: [{
        // pass in any code/data for generic EDNS0 options
        code: 12,
        data: Buffer.alloc(31)
      }, {
        // Several EDNS0 options have enhanced support
        code: 'PADDING',
        length: 31,
      }, {
        code: 'CLIENT_SUBNET',
        family: 2, // 1 for IPv4, 2 for IPv6
        sourcePrefixLength: 64, // used to truncate IP address
        scopePrefixLength: 0,
        ip: 'fe80::',
      }, {
        code: 'TCP_KEEPALIVE',
        timeout: 150 // increments of 100ms.  This means 15s.
      }, {
        code: 'KEY_TAG',
        tags: [1, 2, 3],
      }]
    }

    The options PADDING, CLIENT_SUBNET, TCP_KEEPALIVE and KEY_TAG support enhanced de/encoding. See optionscodes.js for all supported option codes. If the data property is present on a option, it takes precedence. On decoding, data will always be defined.

    PTR

    {
      data: 'points.to.another.record'
    }

    RP

    {
      mbox: 'admin.example.com',
      txt: 'txt.example.com'
    }

    RRSIG

    {
      typeCovered: 'A',
      algorithm: 8,
      labels: 1,
      originalTTL: 3600,
      expiration: timestamp,
      inception: timestamp,
      keyTag: 12345,
      signersName: 'a.name',
      signature: Buffer
    }

    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
      }
    }

    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.

    If you need another record type, open an issue and we'll try to add it.

    License

    MIT

    Install

    npm i dns-packet

    DownloadsWeekly Downloads

    7,914,723

    Version

    5.2.1

    License

    MIT

    Unpacked Size

    55.1 kB

    Total Files

    10

    Last publish

    Collaborators

    • avatar
    • avatar