{"id":13527437,"url":"https://github.com/mafintosh/dns-packet","last_synced_at":"2025-05-14T04:08:44.391Z","repository":{"id":4113912,"uuid":"52037627","full_name":"mafintosh/dns-packet","owner":"mafintosh","description":"An abstract-encoding compliant module for encoding / decoding DNS packets","archived":false,"fork":false,"pushed_at":"2025-04-04T08:50:38.000Z","size":181,"stargazers_count":210,"open_issues_count":24,"forks_count":72,"subscribers_count":16,"default_branch":"master","last_synced_at":"2025-04-11T06:55:50.459Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mafintosh.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2016-02-18T20:48:42.000Z","updated_at":"2025-04-04T08:50:42.000Z","dependencies_parsed_at":"2024-02-12T04:34:53.885Z","dependency_job_id":"b948177d-ef55-4bf9-81ae-4bba9fb642b8","html_url":"https://github.com/mafintosh/dns-packet","commit_stats":{"total_commits":132,"total_committers":16,"mean_commits":8.25,"dds":"0.40909090909090906","last_synced_commit":"519f55d403f0a49dc18dd4d38e321950d921e124"},"previous_names":[],"tags_count":40,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mafintosh%2Fdns-packet","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mafintosh%2Fdns-packet/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mafintosh%2Fdns-packet/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mafintosh%2Fdns-packet/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mafintosh","download_url":"https://codeload.github.com/mafintosh/dns-packet/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248368615,"owners_count":21092406,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-01T06:01:47.900Z","updated_at":"2025-04-11T09:36:22.732Z","avatar_url":"https://github.com/mafintosh.png","language":"JavaScript","funding_links":[],"categories":["JavaScript","Packages","Modules"],"sub_categories":[],"readme":"# dns-packet\n[![](https://img.shields.io/npm/v/dns-packet.svg?style=flat)](https://www.npmjs.org/package/dns-packet) [![](https://img.shields.io/npm/dm/dns-packet.svg)](https://www.npmjs.org/package/dns-packet) [![](https://github.com/github/mafintosh/dns-packet/workflows/ci.yml/badge.svg)](https://github.com/github/mafintosh/dns-packet/workflows/ci.yml) [![Coverage Status](https://coveralls.io/repos/github/mafintosh/dns-packet/badge.svg?branch=master)](https://coveralls.io/github/mafintosh/dns-packet?branch=master)\n\nAn [abstract-encoding](https://github.com/mafintosh/abstract-encoding) compliant module for encoding / decoding DNS packets. Lifted out of [multicast-dns](https://github.com/mafintosh/multicast-dns) as a separate module.\n\n```\nnpm install dns-packet\n```\n\n## UDP Usage\n\n``` js\nconst dnsPacket = require('dns-packet')\nconst dgram = require('dgram')\n\nconst socket = dgram.createSocket('udp4')\n\nconst buf = dnsPacket.encode({\n  type: 'query',\n  id: 1,\n  flags: dnsPacket.RECURSION_DESIRED,\n  questions: [{\n    type: 'A',\n    name: 'google.com'\n  }]\n})\n\nsocket.on('message', message =\u003e {\n  console.log(dnsPacket.decode(message)) // prints out a response from google dns\n})\n\nsocket.send(buf, 0, buf.length, 53, '8.8.8.8')\n```\n\nAlso see [the UDP example](examples/udp.js).\n\n## TCP, TLS, HTTPS\n\nWhile 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:\n\n- [TCP](examples/tcp.js)\n- [DNS over TLS](examples/tls.js)\n- [DNS over HTTPS](examples/doh.js)\n\n## API\n\n#### `var buf = packets.encode(packet, [buf], [offset])`\n\nEncodes a DNS packet into a buffer containing a UDP payload.\n\n#### `var packet = packets.decode(buf, [offset])`\n\nDecode a DNS packet from a buffer containing a UDP payload.\n\n#### `var buf = packets.streamEncode(packet, [buf], [offset])`\n\nEncodes a DNS packet into a buffer containing a TCP payload.\n\n#### `var packet = packets.streamDecode(buf, [offset])`\n\nDecode a DNS packet from a buffer containing a TCP payload.\n\n#### `var len = packets.encodingLength(packet)`\n\nReturns how many bytes are needed to encode the DNS packet\n\n## Packets\n\nPackets look like this\n\n``` js\n{\n  type: 'query|response',\n  id: optionalIdNumber,\n  flags: optionalBitFlags,\n  questions: [...],\n  answers: [...],\n  additionals: [...],\n  authorities: [...]\n}\n```\n\nThe bit flags available are\n\n``` js\npacket.RECURSION_DESIRED\npacket.RECURSION_AVAILABLE\npacket.TRUNCATED_RESPONSE\npacket.AUTHORITATIVE_ANSWER\npacket.AUTHENTIC_DATA\npacket.CHECKING_DISABLED\n```\n\nTo use more than one flag bitwise-or them together\n\n``` js\nvar flags = packet.RECURSION_DESIRED | packet.RECURSION_AVAILABLE\n```\n\nAnd to check for a flag use bitwise-and\n\n``` js\nvar isRecursive = message.flags \u0026 packet.RECURSION_DESIRED\n```\n\nA question looks like this\n\n``` js\n{\n  type: 'A', // or SRV, AAAA, etc\n  class: 'IN', // one of IN, CS, CH, HS, ANY. Default: IN\n  name: 'google.com' // which record are you looking for\n}\n```\n\nAnd an answer, additional, or authority looks like this\n\n``` js\n{\n  type: 'A', // or SRV, AAAA, etc\n  class: 'IN', // one of IN, CS, CH, HS\n  name: 'google.com', // which name is this record for\n  ttl: optionalTimeToLiveInSeconds,\n  (record specific data, see below)\n}\n```\n\n## Supported record types\n\n#### `A`\n\n``` js\n{\n  data: 'IPv4 address' // fx 127.0.0.1\n}\n```\n\n#### `AAAA`\n\n``` js\n{\n  data: 'IPv6 address' // fx fe80::1\n}\n```\n\n#### `CAA`\n\n``` js\n{\n  flags: 128, // octet\n  tag: 'issue|issuewild|iodef',\n  value: 'ca.example.net',\n  issuerCritical: false\n}\n```\n\n#### `CNAME`\n\n``` js\n{\n  data: 'cname.to.another.record'\n}\n```\n\n#### `DNAME`\n\n``` js\n{\n  data: 'dname.to.another.record'\n}\n```\n\n#### `DNSKEY`\n\n``` js\n{\n  flags: 257, // 16 bits\n  algorithm: 1, // octet\n  key: Buffer\n}\n```\n\n#### `DS`\n\n``` js\n{\n  keyTag: 12345,\n  algorithm: 8,\n  digestType: 1,\n  digest: Buffer\n}\n```\n\n#### `HINFO`\n\n``` js\n{\n  data: {\n    cpu: 'cpu info',\n    os: 'os info'\n  }\n}\n```\n\n#### `MX`\n\n``` js\n{\n  preference: 10,\n  exchange: 'mail.example.net'\n}\n```\n\n#### `NAPTR`\n\n``` js\n{\n  data:\n    {\n      order: 100,\n      preference: 10,\n      flags: 's',\n      services: 'SIP+D2U',\n      regexp: '!^.*$!sip:customer-service@example.com!',\n      replacement: '_sip._udp.example.com'\n    }\n}\n```\n\n#### `NS`\n\n``` js\n{\n  data: nameServer\n}\n```\n\n#### `NSEC`\n\n``` js\n{\n  nextDomain: 'a.domain',\n  rrtypes: ['A', 'TXT', 'RRSIG']\n}\n```\n\n#### `NSEC3`\n\n``` js\n{\n  algorithm: 1,\n  flags: 0,\n  iterations: 2,\n  salt: Buffer,\n  nextDomain: Buffer, // Hashed per RFC5155\n  rrtypes: ['A', 'TXT', 'RRSIG']\n}\n```\n\n#### `NULL`\n\n``` js\n{\n  data: Buffer('any binary data')\n}\n```\n\n#### `OPT`\n\n[EDNS0](https://tools.ietf.org/html/rfc6891) options.\n\n``` js\n{\n  type: 'OPT',\n  name: '.',\n  udpPayloadSize: 4096,\n  flags: packet.DNSSEC_OK,\n  options: [{\n    // pass in any code/data for generic EDNS0 options\n    code: 12,\n    data: Buffer.alloc(31)\n  }, {\n    // Several EDNS0 options have enhanced support\n    code: 'PADDING',\n    length: 31,\n  }, {\n    code: 'CLIENT_SUBNET',\n    family: 2, // 1 for IPv4, 2 for IPv6\n    sourcePrefixLength: 64, // used to truncate IP address\n    scopePrefixLength: 0,\n    ip: 'fe80::',\n  }, {\n    code: 'TCP_KEEPALIVE',\n    timeout: 150 // increments of 100ms.  This means 15s.\n  }, {\n    code: 'KEY_TAG',\n    tags: [1, 2, 3],\n  }]\n}\n```\n\nThe options `PADDING`, `CLIENT_SUBNET`, `TCP_KEEPALIVE` and `KEY_TAG` support enhanced de/encoding. See [optionscodes.js](https://github.com/mafintosh/dns-packet/blob/master/optioncodes.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.\n\n#### `PTR`\n\n``` js\n{\n  data: 'points.to.another.record'\n}\n```\n\n#### `RP`\n\n``` js\n{\n  mbox: 'admin.example.com',\n  txt: 'txt.example.com'\n}\n```\n\n#### `SSHFP`\n\n``` js\n{\n  algorithm: 1,\n  hash: 1,\n  fingerprint: 'A108C9F834354D5B37AF988141C9294822F5BC00'\n}\n````\n\n#### `RRSIG`\n\n``` js\n{\n  typeCovered: 'A',\n  algorithm: 8,\n  labels: 1,\n  originalTTL: 3600,\n  expiration: timestamp,\n  inception: timestamp,\n  keyTag: 12345,\n  signersName: 'a.name',\n  signature: Buffer\n}\n```\n\n#### `SOA`\n\n``` js\n{\n  data:\n    {\n      mname: domainName,\n      rname: mailbox,\n      serial: zoneSerial,\n      refresh: refreshInterval,\n      retry: retryInterval,\n      expire: expireInterval,\n      minimum: minimumTTL\n    }\n}\n```\n\n#### `SRV`\n\n``` js\n{\n  data: {\n    port: servicePort,\n    target: serviceHostName,\n    priority: optionalServicePriority,\n    weight: optionalServiceWeight\n  }\n}\n```\n\n#### `TLSA`\n\n``` js\n{\n  usage: 3,\n  selector: 1,\n  matchingType: 1,\n  certificate: Buffer\n}\n```\n\n#### `TXT`\n\n``` js\n{\n  data: 'text' || Buffer || [ Buffer || 'text' ]\n}\n```\n\nWhen 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.\n\nIf you need another record type, open an issue and we'll try to add it.\n\n## License\n\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmafintosh%2Fdns-packet","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmafintosh%2Fdns-packet","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmafintosh%2Fdns-packet/lists"}