From 571e4959cfff207e8192587071beb099e169eca8 Mon Sep 17 00:00:00 2001 From: westley Date: Sat, 4 Mar 2017 17:10:25 -0700 Subject: [PATCH 01/41] soa packer and parser --- packer/type.soa.js | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 packer/type.soa.js diff --git a/packer/type.soa.js b/packer/type.soa.js new file mode 100644 index 0000000..7099853 --- /dev/null +++ b/packer/type.soa.js @@ -0,0 +1,10 @@ +(function (exports) { +'use strict'; + + +exports.DNS_PACKER_TYPE_SOA = function (ab, dv, total, record) { + + return total; +}; + +}('undefined' !== typeof window ? window : exports)); From 0ba8871c3a9f847c1a9353c93b59283b7bf74efc Mon Sep 17 00:00:00 2001 From: westley Date: Sat, 4 Mar 2017 17:11:33 -0700 Subject: [PATCH 02/41] parser soa type --- parser/type.soa.js | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/parser/type.soa.js b/parser/type.soa.js index b468e8a..762a67a 100644 --- a/parser/type.soa.js +++ b/parser/type.soa.js @@ -9,13 +9,28 @@ // Serial Number Unsigned 32-bit integer // Refresh Interval Unsigned 32-bit integer // Retry Interval Unsigned 32-bit integer -// Retry Interval Unsigned 32-bit integer // Expiration Limit Unsigned 32-bit integer // Minimum TTL Unsigned 32-bit integer exports.DNS_PARSER_TYPE_SOA = function (ab, packet, record) { + var rdataAb = ab.slice(record.rdstart, record.rdstart + record.rdlength); + var dv = new DataView(rdataAb) + // Serial Number + record.sn = dv.getUint32(dv.byteLength - 20); + // Refresh Interval + record.ref = dv.getUint32(dv.byteLength - 16); + // Retry Interval + record.ret = dv.getUint32(dv.byteLength - 12); + // Expiration Limit + record.ex = dv.getUint32(dv.byteLength - 8); + // Minimum TTL + record.nx = dv.getUint32(dv.byteLength - 4); + + + return record; + }; }('undefined' !== typeof window ? window : exports)); From 8129863dc61f9ff77b0bc4bd63f0bd831ba0a52f Mon Sep 17 00:00:00 2001 From: westley Date: Sat, 4 Mar 2017 17:20:33 -0700 Subject: [PATCH 03/41] captured soa record type for sample data --- test/soa/soa0.google.com.soa.0.bin | Bin 0 -> 210 bytes test/soa/soa0.google.com.soa.0.json | 203 ++++++++++++++++++++++++ test/soa/soa0.google.com.soa.query.bin | Bin 0 -> 28 bytes test/soa/soa0.google.com.soa.query.json | 19 +++ 4 files changed, 222 insertions(+) create mode 100644 test/soa/soa0.google.com.soa.0.bin create mode 100644 test/soa/soa0.google.com.soa.0.json create mode 100644 test/soa/soa0.google.com.soa.query.bin create mode 100644 test/soa/soa0.google.com.soa.query.json diff --git a/test/soa/soa0.google.com.soa.0.bin b/test/soa/soa0.google.com.soa.0.bin new file mode 100644 index 0000000000000000000000000000000000000000..03f7864735e8ad01e56a6354550b06a69ff04754 GIT binary patch literal 210 zcmazoX>4F%1VR=D7Pj>K{Pdhu=H&cb1_m|;#sfScl7WH2hCz)vuh`@O4`)hVv2J2Y zZf4#A9*!q_ix?P~TOgR71Edb9g9)VL;dcf$pbn!0JV+u;2Q-j)AbCR+d60-PP^1d% n9)^d%7+7w+SKvAj1?9g7@s+p^^g#HJSV4Rht^*p#>eaXa3%xX< literal 0 HcmV?d00001 diff --git a/test/soa/soa0.google.com.soa.0.json b/test/soa/soa0.google.com.soa.0.json new file mode 100644 index 0000000..4ba4b2f --- /dev/null +++ b/test/soa/soa0.google.com.soa.0.json @@ -0,0 +1,203 @@ +{ + "header": { + "id": 23924, + "qr": 1, + "opcode": 0, + "aa": 0, + "tc": 0, + "rd": 1, + "ra": 1, + "res1": 0, + "res2": 0, + "res3": 0, + "rcode": 0 + }, + "qdcount": 1, + "ancount": 1, + "nscount": 4, + "arcount": 4, + "question": [ + { + "name": "google.com", + "type": 6, + "typeName": "SOA", + "class": 1, + "className": "IN", + "byteLength": 16, + "labels": [ + "google", + "com" + ], + "cpcount": 0 + } + ], + "answer": [ + { + "name": "google.com", + "type": 6, + "typeName": "SOA", + "class": 1, + "className": "IN", + "byteLength": 50, + "labels": [ + "google", + "com" + ], + "cpcount": 1, + "rdstart": 40, + "rdlength": 38, + "ttl": 60, + "sn": 149208434, + "ref": 900, + "ret": 900, + "ex": 1800, + "nx": 60 + } + ], + "authority": [ + { + "name": "google.com", + "type": 2, + "typeName": "NS", + "class": 1, + "className": "IN", + "byteLength": 18, + "labels": [ + "google", + "com" + ], + "cpcount": 1, + "rdstart": 90, + "rdlength": 6, + "ttl": 57847, + "data": "ns2.google.com" + }, + { + "name": "google.com", + "type": 2, + "typeName": "NS", + "class": 1, + "className": "IN", + "byteLength": 14, + "labels": [ + "google", + "com" + ], + "cpcount": 1, + "rdstart": 108, + "rdlength": 2, + "ttl": 57847, + "data": "ns4.google.com" + }, + { + "name": "google.com", + "type": 2, + "typeName": "NS", + "class": 1, + "className": "IN", + "byteLength": 18, + "labels": [ + "google", + "com" + ], + "cpcount": 1, + "rdstart": 122, + "rdlength": 6, + "ttl": 57847, + "data": "ns1.google.com" + }, + { + "name": "google.com", + "type": 2, + "typeName": "NS", + "class": 1, + "className": "IN", + "byteLength": 18, + "labels": [ + "google", + "com" + ], + "cpcount": 1, + "rdstart": 140, + "rdlength": 6, + "ttl": 57847, + "data": "ns3.google.com" + } + ], + "edns_options": [], + "additional": [ + { + "name": "ns1.google.com", + "type": 1, + "typeName": "A", + "class": 1, + "className": "IN", + "byteLength": 16, + "labels": [ + "ns1", + "google", + "com" + ], + "cpcount": 2, + "rdstart": 158, + "rdlength": 4, + "ttl": 57850, + "address": "216.239.32.10" + }, + { + "name": "ns2.google.com", + "type": 1, + "typeName": "A", + "class": 1, + "className": "IN", + "byteLength": 16, + "labels": [ + "ns2", + "google", + "com" + ], + "cpcount": 2, + "rdstart": 174, + "rdlength": 4, + "ttl": 57839, + "address": "216.239.34.10" + }, + { + "name": "ns3.google.com", + "type": 1, + "typeName": "A", + "class": 1, + "className": "IN", + "byteLength": 16, + "labels": [ + "ns3", + "google", + "com" + ], + "cpcount": 2, + "rdstart": 190, + "rdlength": 4, + "ttl": 57861, + "address": "216.239.36.10" + }, + { + "name": "ns4.google.com", + "type": 1, + "typeName": "A", + "class": 1, + "className": "IN", + "byteLength": 16, + "labels": [ + "ns4", + "google", + "com" + ], + "cpcount": 2, + "rdstart": 206, + "rdlength": 4, + "ttl": 57850, + "address": "216.239.38.10" + } + ], + "byteLength": 210 +} diff --git a/test/soa/soa0.google.com.soa.query.bin b/test/soa/soa0.google.com.soa.query.bin new file mode 100644 index 0000000000000000000000000000000000000000..d33b6611fd4e91d6ee414df7a16c628127a0a52b GIT binary patch literal 28 dcmazoVPs$cA`oCp&(BZKNo7vX&joTA7y&;T1fT!_ literal 0 HcmV?d00001 diff --git a/test/soa/soa0.google.com.soa.query.json b/test/soa/soa0.google.com.soa.query.json new file mode 100644 index 0000000..1122b4d --- /dev/null +++ b/test/soa/soa0.google.com.soa.query.json @@ -0,0 +1,19 @@ +{ + "header": { + "id": 23924, + "qr": 0, + "opcode": 0, + "aa": 0, + "tc": 0, + "rd": 1, + "ra": 0, + "rcode": 0 + }, + "question": [ + { + "name": "google.com", + "typeName": "SOA", + "className": "IN" + } + ] +} \ No newline at end of file From 4df82c456ed8d0433f4f4fb2d1049c95de753eff Mon Sep 17 00:00:00 2001 From: Daplie Date: Wed, 8 Mar 2017 17:51:41 -0700 Subject: [PATCH 04/41] added NS record packer --- packer/type.ns.js | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 packer/type.ns.js diff --git a/packer/type.ns.js b/packer/type.ns.js new file mode 100644 index 0000000..6c68dcf --- /dev/null +++ b/packer/type.ns.js @@ -0,0 +1,39 @@ +(function (exports) { +'use strict'; + + +// NS name for the supplied domain. May be label, pointer or any combination + +exports.DNS_PACKER_TYPE_NS = function (ab, dv, total, record) { + if(!record.data){ + throw new Error("no data on NS record"); + } + + + var nsLen = 0; + var rdLenIndex = total; + total +=2; + + // RDATA + // a sequence of labels + + record.data.split('.').forEach(function(label) { + nsLen += 1 + label.length; + + dv.setUint8(total, label.length, false); + total += 1; + + label.split('').forEach(function (ch){ + dv.setUint8(total, ch.charCodeAt(0), false); + total += 1; + }); + }); + + // RDLENGTH + dv.setUint16(rdLenIndex, record.data.length + 1, false); + + + return total; +}; + +}('undefined' !== typeof window ? window : exports)); From 43360a75da933a9a2e105c10a128b781945316a2 Mon Sep 17 00:00:00 2001 From: Daplie Date: Wed, 8 Mar 2017 17:53:15 -0700 Subject: [PATCH 05/41] added NS record packer. --- packer/type.ns.js | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 packer/type.ns.js diff --git a/packer/type.ns.js b/packer/type.ns.js new file mode 100644 index 0000000..6c68dcf --- /dev/null +++ b/packer/type.ns.js @@ -0,0 +1,39 @@ +(function (exports) { +'use strict'; + + +// NS name for the supplied domain. May be label, pointer or any combination + +exports.DNS_PACKER_TYPE_NS = function (ab, dv, total, record) { + if(!record.data){ + throw new Error("no data on NS record"); + } + + + var nsLen = 0; + var rdLenIndex = total; + total +=2; + + // RDATA + // a sequence of labels + + record.data.split('.').forEach(function(label) { + nsLen += 1 + label.length; + + dv.setUint8(total, label.length, false); + total += 1; + + label.split('').forEach(function (ch){ + dv.setUint8(total, ch.charCodeAt(0), false); + total += 1; + }); + }); + + // RDLENGTH + dv.setUint16(rdLenIndex, record.data.length + 1, false); + + + return total; +}; + +}('undefined' !== typeof window ? window : exports)); From 05beaa480b3c4121afc8a0bef15a70c40d8718be Mon Sep 17 00:00:00 2001 From: Daplie Date: Wed, 8 Mar 2017 18:59:33 -0700 Subject: [PATCH 06/41] added PTR record packer --- packer/type.ns.js | 1 - packer/type.ptr.js | 37 +++++++++++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+), 1 deletion(-) create mode 100644 packer/type.ptr.js diff --git a/packer/type.ns.js b/packer/type.ns.js index 6c68dcf..20a0ee1 100644 --- a/packer/type.ns.js +++ b/packer/type.ns.js @@ -16,7 +16,6 @@ exports.DNS_PACKER_TYPE_NS = function (ab, dv, total, record) { // RDATA // a sequence of labels - record.data.split('.').forEach(function(label) { nsLen += 1 + label.length; diff --git a/packer/type.ptr.js b/packer/type.ptr.js new file mode 100644 index 0000000..51db54c --- /dev/null +++ b/packer/type.ptr.js @@ -0,0 +1,37 @@ +(function (exports) { +'use strict'; + +// The host name that represents the supplied UP address +// May be a label, pointer or any combination + +exports.DNS_PACKER_TYPE_PTR = function (ab, dv, total, record) { + if (!record.data) { + throw new Error("no data for PTR record"); + } + + var ptrLen = 0; + var rdLenIndex = total; + total += 2; + + // RDATA + // a sequence of labels + record.data.split('.').forEach(function (label){ + console.log("the labels are: " + label); + ptrLen += 1 + label.length; + + dv.setUint8(total, label.length, false); + total += 1; + + label.split('').forEach(function (ch){ + dv.setUint8(total, ch.charCodeAt(0), false); + total += 1; + }); + }); + + // RDLENGTH + dv.setUint16(rdLenIndex, record.data.length + 1, false); + + return total; +}; + +}('undefined' !== typeof window ? window : exports)); From 792bea258d394dc90f2940899a3eea2253f1636c Mon Sep 17 00:00:00 2001 From: Daplie Date: Thu, 9 Mar 2017 15:12:26 -0700 Subject: [PATCH 07/41] finished SRV record data packer. Still need to test exhaustively. Left in debugging code. --- packer/type.srv.js | 73 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) create mode 100644 packer/type.srv.js diff --git a/packer/type.srv.js b/packer/type.srv.js new file mode 100644 index 0000000..63b8440 --- /dev/null +++ b/packer/type.srv.js @@ -0,0 +1,73 @@ +(function (exports) { +'use strict'; + +// SRV RDATA contains: +// Priority: The relative priority of this service. 16-bit (range 0-65535) +// Weight: Used when more than one serivice has the same priority. 16-bit +// (range 0-65535) +// Port: Port number assigned to the symbolic service. 16-bit (range 0-65535) +// Target: The name of the host that will provide service. + +exports.DNS_PACKER_TYPE_SRV = function (ab, dv, total, record) { + + // maybe these should be changed to 'hasOwnProperty' for all of these + // TODO: Check that number is in range 1-64k + if (!record.priority){ + throw new Error("no priority for SRV record"); + } + if (!record.hasOwnProperty('weight')){ + throw new Error("no weight for SRV record"); + } + if (!record.port){ + throw new Error("no port for SRV record"); + } + if (!record.target) { + throw new Error("no target for SRV record"); + } + + // console.log("record length, priority, weight, port, then target"); + // console.log("record priority is: " + record.priority); + // console.log("record weight is: " + record.weight); + // console.log("record port is: " + record.port); + // console.log("record target is: " + record.target); + // console.log("total length currently is: " + total); + + + var srvLen = 6; // 16-bit priority, weight and port = 6 Bytes + var rdLenIndex = total; + + total+=2; + + dv.setUint16(total, parseInt(record.priority, 10), false); + total+=2; + + dv.setUint16(total,parseInt(record.weight, 10), false); + total+=2; + + dv.setUint16(total, parseInt(record.port, 10), false); + total+=2; + + record.target.split('.').forEach(function (label){ + srvLen += 1 + label.length; + + dv.setUint8(total, label.length, false); + total += 1; + + label.split('').forEach(function (ch) { + dv.setUint8(total, ch.charCodeAt(0), false); + total +=1; + }); + }); + + + // RDLENGTH + + dv.setUint16(rdLenIndex, srvLen, false); + + + + + return total; +}; + +}('undefined' !== typeof window ? window : exports)); From 16dd91ace03e60567c54de22996233fb09411249 Mon Sep 17 00:00:00 2001 From: Daplie Date: Thu, 9 Mar 2017 19:22:45 -0700 Subject: [PATCH 08/41] captured some more SOA records. --- test/soa_test/test.america.com.soa.0.bin | Bin 0 -> 97 bytes test/soa_test/test.america.com.soa.0.json | 61 +++++++++++++++++ test/soa_test/test.america.com.soa.query.bin | Bin 0 -> 29 bytes test/soa_test/test.america.com.soa.query.json | 19 ++++++ test/soa_test/test.daplie.com.soa.0.bin | Bin 0 -> 95 bytes test/soa_test/test.daplie.com.soa.0.json | 61 +++++++++++++++++ test/soa_test/test.daplie.com.soa.query.bin | Bin 0 -> 28 bytes test/soa_test/test.daplie.com.soa.query.json | 19 ++++++ .../test.doesntexisit.google.com.soa.0.bin | Bin 0 -> 91 bytes .../test.doesntexisit.google.com.soa.0.json | 62 ++++++++++++++++++ ...test.doesntexisit.google.com.soa.query.bin | Bin 0 -> 41 bytes ...est.doesntexisit.google.com.soa.query.json | 19 ++++++ test/soa_test/test.facebook.com.soa.0.bin | Bin 0 -> 75 bytes test/soa_test/test.facebook.com.soa.0.json | 61 +++++++++++++++++ test/soa_test/test.facebook.com.soa.query.bin | Bin 0 -> 30 bytes .../soa_test/test.facebook.com.soa.query.json | 19 ++++++ test/soa_test/test.gmail.com.soa.0.bin | Bin 0 -> 84 bytes test/soa_test/test.gmail.com.soa.0.json | 61 +++++++++++++++++ test/soa_test/test.gmail.com.soa.query.bin | Bin 0 -> 27 bytes test/soa_test/test.gmail.com.soa.query.json | 19 ++++++ test/soa_test/test.google.com.soa.0.bin | Bin 0 -> 78 bytes test/soa_test/test.google.com.soa.0.json | 61 +++++++++++++++++ test/soa_test/test.google.com.soa.query.bin | Bin 0 -> 28 bytes test/soa_test/test.google.com.soa.query.json | 19 ++++++ test/soa_test/test.khanacademy.com.soa.0.bin | Bin 0 -> 117 bytes test/soa_test/test.khanacademy.com.soa.0.json | 61 +++++++++++++++++ .../test.khanacademy.com.soa.query.bin | Bin 0 -> 33 bytes .../test.khanacademy.com.soa.query.json | 19 ++++++ test/soa_test/test.pinterest.com.soa.0.bin | Bin 0 -> 75 bytes test/soa_test/test.pinterest.com.soa.0.json | 61 +++++++++++++++++ .../soa_test/test.pinterest.com.soa.query.bin | Bin 0 -> 31 bytes .../test.pinterest.com.soa.query.json | 19 ++++++ test/soa_test/test.tinder.com.soa.0.bin | Bin 0 -> 110 bytes test/soa_test/test.tinder.com.soa.0.json | 61 +++++++++++++++++ test/soa_test/test.tinder.com.soa.query.bin | Bin 0 -> 28 bytes test/soa_test/test.tinder.com.soa.query.json | 19 ++++++ 36 files changed, 721 insertions(+) create mode 100644 test/soa_test/test.america.com.soa.0.bin create mode 100644 test/soa_test/test.america.com.soa.0.json create mode 100644 test/soa_test/test.america.com.soa.query.bin create mode 100644 test/soa_test/test.america.com.soa.query.json create mode 100644 test/soa_test/test.daplie.com.soa.0.bin create mode 100644 test/soa_test/test.daplie.com.soa.0.json create mode 100644 test/soa_test/test.daplie.com.soa.query.bin create mode 100644 test/soa_test/test.daplie.com.soa.query.json create mode 100644 test/soa_test/test.doesntexisit.google.com.soa.0.bin create mode 100644 test/soa_test/test.doesntexisit.google.com.soa.0.json create mode 100644 test/soa_test/test.doesntexisit.google.com.soa.query.bin create mode 100644 test/soa_test/test.doesntexisit.google.com.soa.query.json create mode 100644 test/soa_test/test.facebook.com.soa.0.bin create mode 100644 test/soa_test/test.facebook.com.soa.0.json create mode 100644 test/soa_test/test.facebook.com.soa.query.bin create mode 100644 test/soa_test/test.facebook.com.soa.query.json create mode 100644 test/soa_test/test.gmail.com.soa.0.bin create mode 100644 test/soa_test/test.gmail.com.soa.0.json create mode 100644 test/soa_test/test.gmail.com.soa.query.bin create mode 100644 test/soa_test/test.gmail.com.soa.query.json create mode 100644 test/soa_test/test.google.com.soa.0.bin create mode 100644 test/soa_test/test.google.com.soa.0.json create mode 100644 test/soa_test/test.google.com.soa.query.bin create mode 100644 test/soa_test/test.google.com.soa.query.json create mode 100644 test/soa_test/test.khanacademy.com.soa.0.bin create mode 100644 test/soa_test/test.khanacademy.com.soa.0.json create mode 100644 test/soa_test/test.khanacademy.com.soa.query.bin create mode 100644 test/soa_test/test.khanacademy.com.soa.query.json create mode 100644 test/soa_test/test.pinterest.com.soa.0.bin create mode 100644 test/soa_test/test.pinterest.com.soa.0.json create mode 100644 test/soa_test/test.pinterest.com.soa.query.bin create mode 100644 test/soa_test/test.pinterest.com.soa.query.json create mode 100644 test/soa_test/test.tinder.com.soa.0.bin create mode 100644 test/soa_test/test.tinder.com.soa.0.json create mode 100644 test/soa_test/test.tinder.com.soa.query.bin create mode 100644 test/soa_test/test.tinder.com.soa.query.json diff --git a/test/soa_test/test.america.com.soa.0.bin b/test/soa_test/test.america.com.soa.0.bin new file mode 100644 index 0000000000000000000000000000000000000000..484d202358aa7e8cf1f90a10fd1f2fb1d908fed6 GIT binary patch literal 97 zcmaDmp|OF15eR{RJux@6C^I>cIXORks?P07zq%*;#9 s&nqd)&p9B%oRU|}ngtZAV9rY|VW`lmkzimbXkcKFQDES-0@8c}0Eej;YybcN literal 0 HcmV?d00001 diff --git a/test/soa_test/test.america.com.soa.0.json b/test/soa_test/test.america.com.soa.0.json new file mode 100644 index 0000000..16062f9 --- /dev/null +++ b/test/soa_test/test.america.com.soa.0.json @@ -0,0 +1,61 @@ +{ + "header": { + "id": 60816, + "qr": 1, + "opcode": 0, + "aa": 0, + "tc": 0, + "rd": 1, + "ra": 1, + "res1": 0, + "res2": 0, + "res3": 0, + "rcode": 0 + }, + "qdcount": 1, + "ancount": 1, + "nscount": 0, + "arcount": 0, + "question": [ + { + "name": "america.com", + "type": 6, + "typeName": "SOA", + "class": 1, + "className": "IN", + "byteLength": 17, + "labels": [ + "america", + "com" + ], + "cpcount": 0 + } + ], + "answer": [ + { + "name": "america.com", + "type": 6, + "typeName": "SOA", + "class": 1, + "className": "IN", + "byteLength": 68, + "labels": [ + "america", + "com" + ], + "cpcount": 1, + "rdstart": 41, + "rdlength": 56, + "ttl": 3599, + "sn": 2016050200, + "ref": 28800, + "ret": 7200, + "ex": 604800, + "nx": 3600 + } + ], + "authority": [], + "edns_options": [], + "additional": [], + "byteLength": 97 +} \ No newline at end of file diff --git a/test/soa_test/test.america.com.soa.query.bin b/test/soa_test/test.america.com.soa.query.bin new file mode 100644 index 0000000000000000000000000000000000000000..a4e7bfcae61ceb831afa860de9431b85fe838732 GIT binary patch literal 29 gcmaDmfsug$h(LfnF*mg+GdYntIX{X;r1Q>)$fx6f^06gy&YXATM literal 0 HcmV?d00001 diff --git a/test/soa_test/test.daplie.com.soa.0.json b/test/soa_test/test.daplie.com.soa.0.json new file mode 100644 index 0000000..910c526 --- /dev/null +++ b/test/soa_test/test.daplie.com.soa.0.json @@ -0,0 +1,61 @@ +{ + "header": { + "id": 60281, + "qr": 1, + "opcode": 0, + "aa": 0, + "tc": 0, + "rd": 1, + "ra": 1, + "res1": 0, + "res2": 0, + "res3": 0, + "rcode": 0 + }, + "qdcount": 1, + "ancount": 1, + "nscount": 0, + "arcount": 0, + "question": [ + { + "name": "daplie.com", + "type": 6, + "typeName": "SOA", + "class": 1, + "className": "IN", + "byteLength": 16, + "labels": [ + "daplie", + "com" + ], + "cpcount": 0 + } + ], + "answer": [ + { + "name": "daplie.com", + "type": 6, + "typeName": "SOA", + "class": 1, + "className": "IN", + "byteLength": 67, + "labels": [ + "daplie", + "com" + ], + "cpcount": 1, + "rdstart": 40, + "rdlength": 55, + "ttl": 0, + "sn": 2017020100, + "ref": 10800, + "ret": 3600, + "ex": 1209600, + "nx": 1800 + } + ], + "authority": [], + "edns_options": [], + "additional": [], + "byteLength": 95 +} \ No newline at end of file diff --git a/test/soa_test/test.daplie.com.soa.query.bin b/test/soa_test/test.daplie.com.soa.query.bin new file mode 100644 index 0000000000000000000000000000000000000000..6ae4d8f0c7c6753424a83ee49a7d7c17e0753ebc GIT binary patch literal 28 ecmaD|$;iL}L?FPHl30+FnaZ4;p9|zLFaiKhUgBo*Q jvEczp&Xl}j-NcmK%)A4V9B)!{7#NsaAefy4sLloeFlQC5 literal 0 HcmV?d00001 diff --git a/test/soa_test/test.doesntexisit.google.com.soa.0.json b/test/soa_test/test.doesntexisit.google.com.soa.0.json new file mode 100644 index 0000000..4225714 --- /dev/null +++ b/test/soa_test/test.doesntexisit.google.com.soa.0.json @@ -0,0 +1,62 @@ +{ + "header": { + "id": 14537, + "qr": 1, + "opcode": 0, + "aa": 0, + "tc": 0, + "rd": 1, + "ra": 1, + "res1": 0, + "res2": 0, + "res3": 0, + "rcode": 3 + }, + "qdcount": 1, + "ancount": 0, + "nscount": 1, + "arcount": 0, + "question": [ + { + "name": "doesntexisit.google.com", + "type": 6, + "typeName": "SOA", + "class": 1, + "className": "IN", + "byteLength": 29, + "labels": [ + "doesntexisit", + "google", + "com" + ], + "cpcount": 0 + } + ], + "answer": [], + "authority": [ + { + "name": "google.com", + "type": 6, + "typeName": "SOA", + "class": 1, + "className": "IN", + "byteLength": 50, + "labels": [ + "google", + "com" + ], + "cpcount": 1, + "rdstart": 53, + "rdlength": 38, + "ttl": 59, + "sn": 149710188, + "ref": 900, + "ret": 900, + "ex": 1800, + "nx": 60 + } + ], + "edns_options": [], + "additional": [], + "byteLength": 91 +} \ No newline at end of file diff --git a/test/soa_test/test.doesntexisit.google.com.soa.query.bin b/test/soa_test/test.doesntexisit.google.com.soa.query.bin new file mode 100644 index 0000000000000000000000000000000000000000..06efffc9a6c4d41e1c9315dae624b6da99fc0a17 GIT binary patch literal 41 scmcCG$;iL}L?FPElAl_fSCU$hS)5tImY$!Vo|DR)oS)0Uz{bD`0L9D+{{R30 literal 0 HcmV?d00001 diff --git a/test/soa_test/test.doesntexisit.google.com.soa.query.json b/test/soa_test/test.doesntexisit.google.com.soa.query.json new file mode 100644 index 0000000..b1f950d --- /dev/null +++ b/test/soa_test/test.doesntexisit.google.com.soa.query.json @@ -0,0 +1,19 @@ +{ + "header": { + "id": 14537, + "qr": 0, + "opcode": 0, + "aa": 0, + "tc": 0, + "rd": 1, + "ra": 0, + "rcode": 0 + }, + "question": [ + { + "name": "doesntexisit.google.com", + "typeName": "SOA", + "className": "IN" + } + ] +} \ No newline at end of file diff --git a/test/soa_test/test.facebook.com.soa.0.bin b/test/soa_test/test.facebook.com.soa.0.bin new file mode 100644 index 0000000000000000000000000000000000000000..10a5b34de5e2f82f28b12ada7a95c32e9cca115f GIT binary patch literal 75 zcmd=6*Vw?o2!ueuk(QX8nv|cP&77Q{%fP_Kz<7WML;|JC859{4nevJc@Gz%<$cRIX UpBWfr6c`xTIT$#t8h}bF0BqC`z5oCK literal 0 HcmV?d00001 diff --git a/test/soa_test/test.facebook.com.soa.0.json b/test/soa_test/test.facebook.com.soa.0.json new file mode 100644 index 0000000..d6aeab2 --- /dev/null +++ b/test/soa_test/test.facebook.com.soa.0.json @@ -0,0 +1,61 @@ +{ + "header": { + "id": 3582, + "qr": 1, + "opcode": 0, + "aa": 0, + "tc": 0, + "rd": 1, + "ra": 1, + "res1": 0, + "res2": 0, + "res3": 0, + "rcode": 0 + }, + "qdcount": 1, + "ancount": 1, + "nscount": 0, + "arcount": 0, + "question": [ + { + "name": "facebook.com", + "type": 6, + "typeName": "SOA", + "class": 1, + "className": "IN", + "byteLength": 18, + "labels": [ + "facebook", + "com" + ], + "cpcount": 0 + } + ], + "answer": [ + { + "name": "facebook.com", + "type": 6, + "typeName": "SOA", + "class": 1, + "className": "IN", + "byteLength": 45, + "labels": [ + "facebook", + "com" + ], + "cpcount": 1, + "rdstart": 42, + "rdlength": 33, + "ttl": 119, + "sn": 1489109491, + "ref": 7200, + "ret": 1800, + "ex": 604800, + "nx": 120 + } + ], + "authority": [], + "edns_options": [], + "additional": [], + "byteLength": 75 +} \ No newline at end of file diff --git a/test/soa_test/test.facebook.com.soa.query.bin b/test/soa_test/test.facebook.com.soa.query.bin new file mode 100644 index 0000000000000000000000000000000000000000..23e09c475c8996ccc9d8d63a998d530bbf5bf361 GIT binary patch literal 30 hcmd=6$H>3{L?FPCmYAHHl%Jo?oSdJ_z`(}92mn)71(^T< literal 0 HcmV?d00001 diff --git a/test/soa_test/test.facebook.com.soa.query.json b/test/soa_test/test.facebook.com.soa.query.json new file mode 100644 index 0000000..884a7b4 --- /dev/null +++ b/test/soa_test/test.facebook.com.soa.query.json @@ -0,0 +1,19 @@ +{ + "header": { + "id": 3582, + "qr": 0, + "opcode": 0, + "aa": 0, + "tc": 0, + "rd": 1, + "ra": 0, + "rcode": 0 + }, + "question": [ + { + "name": "facebook.com", + "typeName": "SOA", + "className": "IN" + } + ] +} \ No newline at end of file diff --git a/test/soa_test/test.gmail.com.soa.0.bin b/test/soa_test/test.gmail.com.soa.0.bin new file mode 100644 index 0000000000000000000000000000000000000000..dddc1f632f5e51241223c9f53a52a3cfbe9ed24e GIT binary patch literal 84 zcmbQbwXuPL5eR{RH9a>mGlw}jKbL`lje+q14~PVcTQle~=M@{VrRV3T=cFDG;!Mda c)=f;w&CENX&GGur6b1(776@kN04lcu05)h{RE`| literal 0 HcmV?d00001 diff --git a/test/soa_test/test.gmail.com.soa.query.json b/test/soa_test/test.gmail.com.soa.query.json new file mode 100644 index 0000000..c52d2f2 --- /dev/null +++ b/test/soa_test/test.gmail.com.soa.query.json @@ -0,0 +1,19 @@ +{ + "header": { + "id": 38325, + "qr": 0, + "opcode": 0, + "aa": 0, + "tc": 0, + "rd": 1, + "ra": 0, + "rcode": 0 + }, + "question": [ + { + "name": "gmail.com", + "typeName": "SOA", + "className": "IN" + } + ] +} \ No newline at end of file diff --git a/test/soa_test/test.google.com.soa.0.bin b/test/soa_test/test.google.com.soa.0.bin new file mode 100644 index 0000000000000000000000000000000000000000..e7e8d96fba55293e4242eb88960b3d33b59eb490 GIT binary patch literal 78 zcmb<7Y;0g)1VSKSOV7_w&q-xY&d&vM7#I)mfJmT(HG>*+Ua|239?q1!V%@})+|0ZK UJRGn8OkrSPZh>HS4xl<40F7x7!vFvP literal 0 HcmV?d00001 diff --git a/test/soa_test/test.google.com.soa.0.json b/test/soa_test/test.google.com.soa.0.json new file mode 100644 index 0000000..00ed0c9 --- /dev/null +++ b/test/soa_test/test.google.com.soa.0.json @@ -0,0 +1,61 @@ +{ + "header": { + "id": 32561, + "qr": 1, + "opcode": 0, + "aa": 0, + "tc": 0, + "rd": 1, + "ra": 1, + "res1": 0, + "res2": 0, + "res3": 0, + "rcode": 0 + }, + "qdcount": 1, + "ancount": 1, + "nscount": 0, + "arcount": 0, + "question": [ + { + "name": "google.com", + "type": 6, + "typeName": "SOA", + "class": 1, + "className": "IN", + "byteLength": 16, + "labels": [ + "google", + "com" + ], + "cpcount": 0 + } + ], + "answer": [ + { + "name": "google.com", + "type": 6, + "typeName": "SOA", + "class": 1, + "className": "IN", + "byteLength": 50, + "labels": [ + "google", + "com" + ], + "cpcount": 1, + "rdstart": 40, + "rdlength": 38, + "ttl": 59, + "sn": 149683348, + "ref": 900, + "ret": 900, + "ex": 1800, + "nx": 60 + } + ], + "authority": [], + "edns_options": [], + "additional": [], + "byteLength": 78 +} \ No newline at end of file diff --git a/test/soa_test/test.google.com.soa.query.bin b/test/soa_test/test.google.com.soa.query.bin new file mode 100644 index 0000000000000000000000000000000000000000..3002d00b2608eb0894806048840ea5ae282f658c GIT binary patch literal 28 dcmb<7WMp6fA`oCp&(BZKNo7vX&joTA7y&!M1b+Yk literal 0 HcmV?d00001 diff --git a/test/soa_test/test.google.com.soa.query.json b/test/soa_test/test.google.com.soa.query.json new file mode 100644 index 0000000..0b77bf4 --- /dev/null +++ b/test/soa_test/test.google.com.soa.query.json @@ -0,0 +1,19 @@ +{ + "header": { + "id": 32561, + "qr": 0, + "opcode": 0, + "aa": 0, + "tc": 0, + "rd": 1, + "ra": 0, + "rcode": 0 + }, + "question": [ + { + "name": "google.com", + "typeName": "SOA", + "className": "IN" + } + ] +} \ No newline at end of file diff --git a/test/soa_test/test.khanacademy.com.soa.0.bin b/test/soa_test/test.khanacademy.com.soa.0.bin new file mode 100644 index 0000000000000000000000000000000000000000..15572858fac9a06dd5cbcde9b4b138e8fc30dd3b GIT binary patch literal 117 zcmb2S+StIr2!ueuot=@GmzbQGlA2q|oSdJ_z`(}9cz_2)GB7YVGkCD)73&%q7#njY zmKUc0*=9ye$@xsB*$jeEfsFj(lHA1NlGGx$#N5QH{JaAaKy!h*WfXuWv@i&j0(pTA E0GE>-x&QzG literal 0 HcmV?d00001 diff --git a/test/soa_test/test.khanacademy.com.soa.0.json b/test/soa_test/test.khanacademy.com.soa.0.json new file mode 100644 index 0000000..42b9feb --- /dev/null +++ b/test/soa_test/test.khanacademy.com.soa.0.json @@ -0,0 +1,61 @@ +{ + "header": { + "id": 7381, + "qr": 1, + "opcode": 0, + "aa": 0, + "tc": 0, + "rd": 1, + "ra": 1, + "res1": 0, + "res2": 0, + "res3": 0, + "rcode": 0 + }, + "qdcount": 1, + "ancount": 1, + "nscount": 0, + "arcount": 0, + "question": [ + { + "name": "khanacademy.com", + "type": 6, + "typeName": "SOA", + "class": 1, + "className": "IN", + "byteLength": 21, + "labels": [ + "khanacademy", + "com" + ], + "cpcount": 0 + } + ], + "answer": [ + { + "name": "khanacademy.com", + "type": 6, + "typeName": "SOA", + "class": 1, + "className": "IN", + "byteLength": 84, + "labels": [ + "khanacademy", + "com" + ], + "cpcount": 1, + "rdstart": 45, + "rdlength": 72, + "ttl": 899, + "sn": 1, + "ref": 7200, + "ret": 900, + "ex": 1209600, + "nx": 86400 + } + ], + "authority": [], + "edns_options": [], + "additional": [], + "byteLength": 117 +} \ No newline at end of file diff --git a/test/soa_test/test.khanacademy.com.soa.query.bin b/test/soa_test/test.khanacademy.com.soa.query.bin new file mode 100644 index 0000000000000000000000000000000000000000..bc9651548b680bf61020a029d3960c0aea1ff4c8 GIT binary patch literal 33 kcmb2S%E-U~L?FPOospQAn4FlBnp?@7oS)0Uz{bD`0BZCGz5oCK literal 0 HcmV?d00001 diff --git a/test/soa_test/test.khanacademy.com.soa.query.json b/test/soa_test/test.khanacademy.com.soa.query.json new file mode 100644 index 0000000..926a1e6 --- /dev/null +++ b/test/soa_test/test.khanacademy.com.soa.query.json @@ -0,0 +1,19 @@ +{ + "header": { + "id": 7381, + "qr": 0, + "opcode": 0, + "aa": 0, + "tc": 0, + "rd": 1, + "ra": 0, + "rcode": 0 + }, + "question": [ + { + "name": "khanacademy.com", + "typeName": "SOA", + "className": "IN" + } + ] +} \ No newline at end of file diff --git a/test/soa_test/test.pinterest.com.soa.0.bin b/test/soa_test/test.pinterest.com.soa.0.bin new file mode 100644 index 0000000000000000000000000000000000000000..3e720bdaf33b6fa95f154ce272dbceb4c3511a8c GIT binary patch literal 75 zcmdO$)!4wm2!ueuS&*4ml3J8nT*923pUc3&#=v-h2ShS3FlsX>Fy|E;9^he4$twnm YGBCbnVBiyAU|@=1;IwLBU|{C}09AJmM*si- literal 0 HcmV?d00001 diff --git a/test/soa_test/test.pinterest.com.soa.0.json b/test/soa_test/test.pinterest.com.soa.0.json new file mode 100644 index 0000000..1c15262 --- /dev/null +++ b/test/soa_test/test.pinterest.com.soa.0.json @@ -0,0 +1,61 @@ +{ + "header": { + "id": 11674, + "qr": 1, + "opcode": 0, + "aa": 0, + "tc": 0, + "rd": 1, + "ra": 1, + "res1": 0, + "res2": 0, + "res3": 0, + "rcode": 0 + }, + "qdcount": 1, + "ancount": 1, + "nscount": 0, + "arcount": 0, + "question": [ + { + "name": "pinterest.com", + "type": 6, + "typeName": "SOA", + "class": 1, + "className": "IN", + "byteLength": 19, + "labels": [ + "pinterest", + "com" + ], + "cpcount": 0 + } + ], + "answer": [ + { + "name": "pinterest.com", + "type": 6, + "typeName": "SOA", + "class": 1, + "className": "IN", + "byteLength": 44, + "labels": [ + "pinterest", + "com" + ], + "cpcount": 1, + "rdstart": 43, + "rdlength": 32, + "ttl": 299, + "sn": 493, + "ref": 3600, + "ret": 600, + "ex": 604800, + "nx": 1800 + } + ], + "authority": [], + "edns_options": [], + "additional": [], + "byteLength": 75 +} \ No newline at end of file diff --git a/test/soa_test/test.pinterest.com.soa.query.bin b/test/soa_test/test.pinterest.com.soa.query.bin new file mode 100644 index 0000000000000000000000000000000000000000..107bea3c27a42b9cb324eac1c21a14b0c3c1eb9f GIT binary patch literal 31 icmdO$#mK+_L?FOfkeOGKT9jH`!knC+%fP_Kzz6_WX9fBI literal 0 HcmV?d00001 diff --git a/test/soa_test/test.pinterest.com.soa.query.json b/test/soa_test/test.pinterest.com.soa.query.json new file mode 100644 index 0000000..bad0db7 --- /dev/null +++ b/test/soa_test/test.pinterest.com.soa.query.json @@ -0,0 +1,19 @@ +{ + "header": { + "id": 11674, + "qr": 0, + "opcode": 0, + "aa": 0, + "tc": 0, + "rd": 1, + "ra": 0, + "rcode": 0 + }, + "question": [ + { + "name": "pinterest.com", + "typeName": "SOA", + "className": "IN" + } + ] +} \ No newline at end of file diff --git a/test/soa_test/test.tinder.com.soa.0.bin b/test/soa_test/test.tinder.com.soa.0.bin new file mode 100644 index 0000000000000000000000000000000000000000..80f4f7324a51d97f325eb11187989ac4625656d0 GIT binary patch literal 110 zcmWHJZERp*1VSKSE6L1DNiAYd&d&vM7#I)mfJg=g=6nV>_PkEw woH@TJok0-F&B!k<$xSRSNiAYa%uTGy&pRLtG!Up)Mgge5g+Ztk$O~)$0Cyc43IG5A literal 0 HcmV?d00001 diff --git a/test/soa_test/test.tinder.com.soa.0.json b/test/soa_test/test.tinder.com.soa.0.json new file mode 100644 index 0000000..3ff3101 --- /dev/null +++ b/test/soa_test/test.tinder.com.soa.0.json @@ -0,0 +1,61 @@ +{ + "header": { + "id": 21341, + "qr": 1, + "opcode": 0, + "aa": 0, + "tc": 0, + "rd": 1, + "ra": 1, + "res1": 0, + "res2": 0, + "res3": 0, + "rcode": 0 + }, + "qdcount": 1, + "ancount": 1, + "nscount": 0, + "arcount": 0, + "question": [ + { + "name": "tinder.com", + "type": 6, + "typeName": "SOA", + "class": 1, + "className": "IN", + "byteLength": 16, + "labels": [ + "tinder", + "com" + ], + "cpcount": 0 + } + ], + "answer": [ + { + "name": "tinder.com", + "type": 6, + "typeName": "SOA", + "class": 1, + "className": "IN", + "byteLength": 82, + "labels": [ + "tinder", + "com" + ], + "cpcount": 1, + "rdstart": 40, + "rdlength": 70, + "ttl": 879, + "sn": 1, + "ref": 7200, + "ret": 900, + "ex": 1209600, + "nx": 86400 + } + ], + "authority": [], + "edns_options": [], + "additional": [], + "byteLength": 110 +} \ No newline at end of file diff --git a/test/soa_test/test.tinder.com.soa.query.bin b/test/soa_test/test.tinder.com.soa.query.bin new file mode 100644 index 0000000000000000000000000000000000000000..fd01e4c6d056d26aae562d4513f17d3eb5c937b2 GIT binary patch literal 28 dcmWHJWn^FgA`oCJ$;?YhEn-g2&joTA7yQc(3t literal 0 HcmV?d00001 diff --git a/test/soa_test/test.tinder.com.soa.query.json b/test/soa_test/test.tinder.com.soa.query.json new file mode 100644 index 0000000..3e08596 --- /dev/null +++ b/test/soa_test/test.tinder.com.soa.query.json @@ -0,0 +1,19 @@ +{ + "header": { + "id": 21341, + "qr": 0, + "opcode": 0, + "aa": 0, + "tc": 0, + "rd": 1, + "ra": 0, + "rcode": 0 + }, + "question": [ + { + "name": "tinder.com", + "typeName": "SOA", + "className": "IN" + } + ] +} \ No newline at end of file From 12cb2887fa47e5a8c86ed69f629c07f0fd193967 Mon Sep 17 00:00:00 2001 From: Daplie Date: Thu, 9 Mar 2017 19:34:27 -0700 Subject: [PATCH 09/41] still working on it --- packer/type.cname.js | 14 +- packer/type.soa.js | 20 +++ packer/type.txt.js | 38 +++++ parser/type.soa.js | 28 +++- test/soa/soa0.google.com.soa.0.bin | Bin 210 -> 0 bytes test/soa/soa0.google.com.soa.0.json | 203 ------------------------ test/soa/soa0.google.com.soa.query.bin | Bin 28 -> 0 bytes test/soa/soa0.google.com.soa.query.json | 19 --- 8 files changed, 90 insertions(+), 232 deletions(-) create mode 100644 packer/type.txt.js delete mode 100644 test/soa/soa0.google.com.soa.0.bin delete mode 100644 test/soa/soa0.google.com.soa.0.json delete mode 100644 test/soa/soa0.google.com.soa.query.bin delete mode 100644 test/soa/soa0.google.com.soa.query.json diff --git a/packer/type.cname.js b/packer/type.cname.js index 3ca92fe..afa823e 100644 --- a/packer/type.cname.js +++ b/packer/type.cname.js @@ -15,14 +15,14 @@ exports.DNS_PACKER_TYPE_CNAME = function (ab, dv, total, record) { // RDATA // a sequence of labels record.data.split('.').forEach(function (label) { - cnameLen += 1 + label.length; - - dv.setUint8(total, label.length, false); - total += 1; + cnameLen += 1 + label.length; + + dv.setUint8(total, label.length, false); + total += 1; - label.split('').forEach(function (ch) { - dv.setUint8(total, ch.charCodeAt(0), false); - total += 1; + label.split('').forEach(function (ch) { + dv.setUint8(total, ch.charCodeAt(0), false); + total += 1; }); }); diff --git a/packer/type.soa.js b/packer/type.soa.js index 7099853..f80ba99 100644 --- a/packer/type.soa.js +++ b/packer/type.soa.js @@ -2,7 +2,27 @@ 'use strict'; + + exports.DNS_PACKER_TYPE_SOA = function (ab, dv, total, record) { + if(!record.sn){ + throw new Error("no serial number for SOA record"); + } + if(!record.ref){ + throw new Error("no serial number for SOA record"); + } + if(!record.ret){ + throw new Error("no serial number for SOA record"); + } + if(!record.ex){ + throw new Error("no serial number for SOA record"); + } + if(!record.nx){ + throw new Error("no serial number for SOA record"); + } + + + return total; }; diff --git a/packer/type.txt.js b/packer/type.txt.js new file mode 100644 index 0000000..ee7e0ee --- /dev/null +++ b/packer/type.txt.js @@ -0,0 +1,38 @@ +(function (exports) { +'use strict'; + +// Record type is just any text. + +exports.DNS_PACKER_TYPE_TXT = function (ab, dv, total, record) { + // if (!record.data){ + // throw new Error("no data for TXT record"); + // } + + + // console.log("record data is: " + record.data); + + // var txtLen = 0; + // var rdLenIndex = total; + // total += 2; + + // //RDATA + // // a sequence of labels + // record.data.split('.').forEach(function (label) { + // txtLen += 1 + label.length; + + // dv.setUint8(total, label.length, false); + // total += 1; + + // label.split('').forEach(function (ch) { + // dv.setUint8(total, ch.charCodeAt(0), false); + // total += 1; + // }); + // }); + + // // RDLENGTH + // dv.setUint16(rdLenIndex, record.data.length + 1, false); + + // return total; +}; + +}('undefined' !== typeof window ? window : exports)); diff --git a/parser/type.soa.js b/parser/type.soa.js index 762a67a..6550f8f 100644 --- a/parser/type.soa.js +++ b/parser/type.soa.js @@ -1,7 +1,7 @@ (function (exports) { 'use strict'; -// TODO. Not yet implemented +// TODO. Not yet implemented. Do we need to include the name server and email address record properties??? // Value Meaning/Use // Primary NS Variable length. The name of the Primary Master for the domain. May be a label, pointer, or any combination @@ -12,11 +12,33 @@ // Expiration Limit Unsigned 32-bit integer // Minimum TTL Unsigned 32-bit integer +var unpackLabels = exports.DNS_UNPACK_LABELS || require('../dns.unpack-labels.js').DNS_UNPACK_LABELS; exports.DNS_PARSER_TYPE_SOA = function (ab, packet, record) { var rdataAb = ab.slice(record.rdstart, record.rdstart + record.rdlength); - var dv = new DataView(rdataAb) + var dv = new DataView(rdataAb); + var cpcount = unpackLabels(new Uint8Array(ab), record.rdstart, { byteLength: 0, cpcount: 0, labels: [], name: '' }).cpcount; + var offset = unpackLabels(new Uint8Array(ab), record.rdstart, { byteLength: 0, cpcount: 0, labels: [], name: '' }).byteLength; + + + for(var i = 0; i < dv.byteLength;i++){ + + console.log(parseInt(dv.getUint8(i), 10).toString(16)); + } + + // Primary NS + //record.name_server = unpackLabels(new Uint8Array(ab), record.rdstart, { byteLength: 0, cpcount: 0, labels: [], name: '' }).name; + // var offset = unpackLabels(new Uint8Array(ab), record.rdstart, { byteLength: 0, cpcount: 0, labels: [], name: '' }).byteLength; + // Admin MB. This email address is always preceeded by 6 Bytes of the name_server data and email_addr length. + // ie: ns1.example.com, where ns1 is 3 bytes, example.com represented by 2 bytes (c0 0c - compression pointer) and then + // 1 more byte representing the email_addr length. + // TODO: email_addr probably shouldn't be parsed this way. The email_addr length byte is probably there to parse this in a more robust way + // we just have to figure that out + + //record.email_addr = unpackLabels(new Uint8Array(ab), record.rdstart+offset, { byteLength: 0, cpcount: 0, labels: [], name: '' }).name; + + // Serial Number record.sn = dv.getUint32(dv.byteLength - 20); // Refresh Interval @@ -27,7 +49,7 @@ exports.DNS_PARSER_TYPE_SOA = function (ab, packet, record) { record.ex = dv.getUint32(dv.byteLength - 8); // Minimum TTL record.nx = dv.getUint32(dv.byteLength - 4); - + return record; diff --git a/test/soa/soa0.google.com.soa.0.bin b/test/soa/soa0.google.com.soa.0.bin deleted file mode 100644 index 03f7864735e8ad01e56a6354550b06a69ff04754..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 210 zcmazoX>4F%1VR=D7Pj>K{Pdhu=H&cb1_m|;#sfScl7WH2hCz)vuh`@O4`)hVv2J2Y zZf4#A9*!q_ix?P~TOgR71Edb9g9)VL;dcf$pbn!0JV+u;2Q-j)AbCR+d60-PP^1d% n9)^d%7+7w+SKvAj1?9g7@s+p^^g#HJSV4Rht^*p#>eaXa3%xX< diff --git a/test/soa/soa0.google.com.soa.0.json b/test/soa/soa0.google.com.soa.0.json deleted file mode 100644 index 4ba4b2f..0000000 --- a/test/soa/soa0.google.com.soa.0.json +++ /dev/null @@ -1,203 +0,0 @@ -{ - "header": { - "id": 23924, - "qr": 1, - "opcode": 0, - "aa": 0, - "tc": 0, - "rd": 1, - "ra": 1, - "res1": 0, - "res2": 0, - "res3": 0, - "rcode": 0 - }, - "qdcount": 1, - "ancount": 1, - "nscount": 4, - "arcount": 4, - "question": [ - { - "name": "google.com", - "type": 6, - "typeName": "SOA", - "class": 1, - "className": "IN", - "byteLength": 16, - "labels": [ - "google", - "com" - ], - "cpcount": 0 - } - ], - "answer": [ - { - "name": "google.com", - "type": 6, - "typeName": "SOA", - "class": 1, - "className": "IN", - "byteLength": 50, - "labels": [ - "google", - "com" - ], - "cpcount": 1, - "rdstart": 40, - "rdlength": 38, - "ttl": 60, - "sn": 149208434, - "ref": 900, - "ret": 900, - "ex": 1800, - "nx": 60 - } - ], - "authority": [ - { - "name": "google.com", - "type": 2, - "typeName": "NS", - "class": 1, - "className": "IN", - "byteLength": 18, - "labels": [ - "google", - "com" - ], - "cpcount": 1, - "rdstart": 90, - "rdlength": 6, - "ttl": 57847, - "data": "ns2.google.com" - }, - { - "name": "google.com", - "type": 2, - "typeName": "NS", - "class": 1, - "className": "IN", - "byteLength": 14, - "labels": [ - "google", - "com" - ], - "cpcount": 1, - "rdstart": 108, - "rdlength": 2, - "ttl": 57847, - "data": "ns4.google.com" - }, - { - "name": "google.com", - "type": 2, - "typeName": "NS", - "class": 1, - "className": "IN", - "byteLength": 18, - "labels": [ - "google", - "com" - ], - "cpcount": 1, - "rdstart": 122, - "rdlength": 6, - "ttl": 57847, - "data": "ns1.google.com" - }, - { - "name": "google.com", - "type": 2, - "typeName": "NS", - "class": 1, - "className": "IN", - "byteLength": 18, - "labels": [ - "google", - "com" - ], - "cpcount": 1, - "rdstart": 140, - "rdlength": 6, - "ttl": 57847, - "data": "ns3.google.com" - } - ], - "edns_options": [], - "additional": [ - { - "name": "ns1.google.com", - "type": 1, - "typeName": "A", - "class": 1, - "className": "IN", - "byteLength": 16, - "labels": [ - "ns1", - "google", - "com" - ], - "cpcount": 2, - "rdstart": 158, - "rdlength": 4, - "ttl": 57850, - "address": "216.239.32.10" - }, - { - "name": "ns2.google.com", - "type": 1, - "typeName": "A", - "class": 1, - "className": "IN", - "byteLength": 16, - "labels": [ - "ns2", - "google", - "com" - ], - "cpcount": 2, - "rdstart": 174, - "rdlength": 4, - "ttl": 57839, - "address": "216.239.34.10" - }, - { - "name": "ns3.google.com", - "type": 1, - "typeName": "A", - "class": 1, - "className": "IN", - "byteLength": 16, - "labels": [ - "ns3", - "google", - "com" - ], - "cpcount": 2, - "rdstart": 190, - "rdlength": 4, - "ttl": 57861, - "address": "216.239.36.10" - }, - { - "name": "ns4.google.com", - "type": 1, - "typeName": "A", - "class": 1, - "className": "IN", - "byteLength": 16, - "labels": [ - "ns4", - "google", - "com" - ], - "cpcount": 2, - "rdstart": 206, - "rdlength": 4, - "ttl": 57850, - "address": "216.239.38.10" - } - ], - "byteLength": 210 -} diff --git a/test/soa/soa0.google.com.soa.query.bin b/test/soa/soa0.google.com.soa.query.bin deleted file mode 100644 index d33b6611fd4e91d6ee414df7a16c628127a0a52b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 28 dcmazoVPs$cA`oCp&(BZKNo7vX&joTA7y&;T1fT!_ diff --git a/test/soa/soa0.google.com.soa.query.json b/test/soa/soa0.google.com.soa.query.json deleted file mode 100644 index 1122b4d..0000000 --- a/test/soa/soa0.google.com.soa.query.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "header": { - "id": 23924, - "qr": 0, - "opcode": 0, - "aa": 0, - "tc": 0, - "rd": 1, - "ra": 0, - "rcode": 0 - }, - "question": [ - { - "name": "google.com", - "typeName": "SOA", - "className": "IN" - } - ] -} \ No newline at end of file From 50b134f33b7c18a72eafd379f0bd3bc542069aa8 Mon Sep 17 00:00:00 2001 From: Daplie Date: Wed, 15 Mar 2017 17:55:59 -0600 Subject: [PATCH 10/41] SOA record can be parsed if there are no compression pointers present in the rdata --- parser/type.soa.js | 36 +++++++++++++++++++++++++----------- 1 file changed, 25 insertions(+), 11 deletions(-) diff --git a/parser/type.soa.js b/parser/type.soa.js index 6550f8f..175047b 100644 --- a/parser/type.soa.js +++ b/parser/type.soa.js @@ -20,35 +20,49 @@ exports.DNS_PARSER_TYPE_SOA = function (ab, packet, record) { var dv = new DataView(rdataAb); var cpcount = unpackLabels(new Uint8Array(ab), record.rdstart, { byteLength: 0, cpcount: 0, labels: [], name: '' }).cpcount; var offset = unpackLabels(new Uint8Array(ab), record.rdstart, { byteLength: 0, cpcount: 0, labels: [], name: '' }).byteLength; - - + var labels = unpackLabels(new Uint8Array(ab), record.rdstart, { byteLength: 0, cpcount: 0, labels: [], name: '' }).labels; + console.log("offset is: " + offset); + console.log("cpcount is: " + cpcount); + console.log("the labels are : " + labels); + console.log("rdstart is: " + record.rdstart); for(var i = 0; i < dv.byteLength;i++){ console.log(parseInt(dv.getUint8(i), 10).toString(16)); } // Primary NS - //record.name_server = unpackLabels(new Uint8Array(ab), record.rdstart, { byteLength: 0, cpcount: 0, labels: [], name: '' }).name; + record.name_server = unpackLabels(new Uint8Array(ab), record.rdstart, { byteLength: 0, cpcount: 0, labels: [], name: '' }).name; // var offset = unpackLabels(new Uint8Array(ab), record.rdstart, { byteLength: 0, cpcount: 0, labels: [], name: '' }).byteLength; // Admin MB. This email address is always preceeded by 6 Bytes of the name_server data and email_addr length. // ie: ns1.example.com, where ns1 is 3 bytes, example.com represented by 2 bytes (c0 0c - compression pointer) and then // 1 more byte representing the email_addr length. // TODO: email_addr probably shouldn't be parsed this way. The email_addr length byte is probably there to parse this in a more robust way // we just have to figure that out - - //record.email_addr = unpackLabels(new Uint8Array(ab), record.rdstart+offset, { byteLength: 0, cpcount: 0, labels: [], name: '' }).name; - + + if (cpcount > 0){ + // do something awesome with compression pointers to get the email address + + console.log("name server length is: " + record.name_server.length); + var email_len = parseInt(dv.getUint8(0), 10) + ;dv.getUint16(0) + console.log("email_start is: " + email_len); + record.email_addr = unpackLabels(new Uint8Array(ab), record.rdstart , { byteLength: 0, cpcount: 0, labels: [], name: '' }).name; + + } + else { + + record.email_addr = unpackLabels(new Uint8Array(ab), record.rdstart + offset, { byteLength: 0, cpcount: 0, labels: [], name: '' }).name; + } // Serial Number - record.sn = dv.getUint32(dv.byteLength - 20); + record.sn = dv.getUint32(dv.byteLength - 20, false); // Refresh Interval - record.ref = dv.getUint32(dv.byteLength - 16); + record.ref = dv.getUint32(dv.byteLength - 16, false); // Retry Interval - record.ret = dv.getUint32(dv.byteLength - 12); + record.ret = dv.getUint32(dv.byteLength - 12, false); // Expiration Limit - record.ex = dv.getUint32(dv.byteLength - 8); + record.ex = dv.getUint32(dv.byteLength - 8, false); // Minimum TTL - record.nx = dv.getUint32(dv.byteLength - 4); + record.nx = dv.getUint32(dv.byteLength - 4, false); return record; From 2388b46c748f239359e5bf1695f91f83415b1baf Mon Sep 17 00:00:00 2001 From: Daplie Date: Wed, 15 Mar 2017 20:24:03 -0600 Subject: [PATCH 11/41] sort of round about way to get the email property of SOA RDATA. Let me know if theirs a better way --- parser/type.soa.js | 39 ++++++++++++++++++--------------------- 1 file changed, 18 insertions(+), 21 deletions(-) diff --git a/parser/type.soa.js b/parser/type.soa.js index 175047b..1a3f834 100644 --- a/parser/type.soa.js +++ b/parser/type.soa.js @@ -18,41 +18,38 @@ exports.DNS_PARSER_TYPE_SOA = function (ab, packet, record) { var rdataAb = ab.slice(record.rdstart, record.rdstart + record.rdlength); var dv = new DataView(rdataAb); + + // we need this information for this parser var cpcount = unpackLabels(new Uint8Array(ab), record.rdstart, { byteLength: 0, cpcount: 0, labels: [], name: '' }).cpcount; var offset = unpackLabels(new Uint8Array(ab), record.rdstart, { byteLength: 0, cpcount: 0, labels: [], name: '' }).byteLength; var labels = unpackLabels(new Uint8Array(ab), record.rdstart, { byteLength: 0, cpcount: 0, labels: [], name: '' }).labels; - console.log("offset is: " + offset); - console.log("cpcount is: " + cpcount); - console.log("the labels are : " + labels); - console.log("rdstart is: " + record.rdstart); - for(var i = 0; i < dv.byteLength;i++){ - - console.log(parseInt(dv.getUint8(i), 10).toString(16)); - } // Primary NS record.name_server = unpackLabels(new Uint8Array(ab), record.rdstart, { byteLength: 0, cpcount: 0, labels: [], name: '' }).name; - // var offset = unpackLabels(new Uint8Array(ab), record.rdstart, { byteLength: 0, cpcount: 0, labels: [], name: '' }).byteLength; - // Admin MB. This email address is always preceeded by 6 Bytes of the name_server data and email_addr length. - // ie: ns1.example.com, where ns1 is 3 bytes, example.com represented by 2 bytes (c0 0c - compression pointer) and then - // 1 more byte representing the email_addr length. - // TODO: email_addr probably shouldn't be parsed this way. The email_addr length byte is probably there to parse this in a more robust way - // we just have to figure that out - - + + // if there exists compression pointers in the rdata if (cpcount > 0){ // do something awesome with compression pointers to get the email address + // I need the length of all the data before the email address starts. + // if there are compression pointers then there will be a byte to indicate the length of each label, the label, + // then there will be a compression pointer to grab the longest label. - console.log("name server length is: " + record.name_server.length); - var email_len = parseInt(dv.getUint8(0), 10) + ;dv.getUint16(0) - console.log("email_start is: " + email_len); - record.email_addr = unpackLabels(new Uint8Array(ab), record.rdstart , { byteLength: 0, cpcount: 0, labels: [], name: '' }).name; + var start = 2; // start or email_addr. take into account compression pointer and address length + for(var i = 0; i < labels.length; i++){ - } + // increase start by the label length. the +1 is to take into account the next label size byte + start = start + labels[i].length + 1; + // check for cpcount. 2 counts behind + if(parseInt(dv.getUint8(start - 2), 10) === 192){ + record.email_addr = unpackLabels(new Uint8Array(ab), record.rdstart + start ,{ byteLength: 0, cpcount: 0, labels: [], name: '' }).name; + } + } + } // if there are no compression pointers, we can get the email address directly from the offset else { record.email_addr = unpackLabels(new Uint8Array(ab), record.rdstart + offset, { byteLength: 0, cpcount: 0, labels: [], name: '' }).name; } + // Serial Number record.sn = dv.getUint32(dv.byteLength - 20, false); // Refresh Interval From cfae86e5f17cdcdc5de259e0628d09d3d0c8e598 Mon Sep 17 00:00:00 2001 From: westley Date: Sat, 18 Mar 2017 11:38:43 -0600 Subject: [PATCH 12/41] tested soa packer. It works, but doesn't utilize compression pointers to full capabilities --- packer/type.soa.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packer/type.soa.js b/packer/type.soa.js index c716c72..d79a9f5 100644 --- a/packer/type.soa.js +++ b/packer/type.soa.js @@ -27,7 +27,7 @@ exports.DNS_PACKER_TYPE_SOA = function (ab, dv, total, record) { } if(!record.ret){ throw new Error("no serial number for SOA record"); - } + } if(!record.ex){ throw new Error("no serial number for SOA record"); } @@ -35,7 +35,7 @@ exports.DNS_PACKER_TYPE_SOA = function (ab, dv, total, record) { throw new Error("no serial number for SOA record"); } - var soaLen = 20; // take into account sn, ref, ret, ex, and nx + var soaLen = 20; // take into account sn, ref, ret, ex, and nx // (32-bits each. 4Bytes * 5 = 20) var rdLenIndex = total; total += 2; // Save space for RDLENGTH @@ -72,7 +72,7 @@ exports.DNS_PACKER_TYPE_SOA = function (ab, dv, total, record) { dv.setUint32(total, parseInt(record.ref, 10), false); total+=4; dv.setUint32(total, parseInt(record.ret, 10), false); - total+=4; + total+=4; dv.setUint32(total, parseInt(record.ex, 10), false); total+=4; dv.setUint32(total, parseInt(record.nx, 10), false); From 28fbc448246617165e350e81949c1a051d247a78 Mon Sep 17 00:00:00 2001 From: westley Date: Sat, 18 Mar 2017 11:40:14 -0600 Subject: [PATCH 13/41] wrote the code but dns.rdat.pack.js is having trouble finding the packer for some reason. --- packer/type.txt.js | 49 ++++++++++++++++++++++------------------------ 1 file changed, 23 insertions(+), 26 deletions(-) diff --git a/packer/type.txt.js b/packer/type.txt.js index ee7e0ee..93cfb4f 100644 --- a/packer/type.txt.js +++ b/packer/type.txt.js @@ -4,35 +4,32 @@ // Record type is just any text. exports.DNS_PACKER_TYPE_TXT = function (ab, dv, total, record) { - // if (!record.data){ - // throw new Error("no data for TXT record"); - // } + if (!record.data){ + throw new Error("no data for TXT record"); + } + + var txtLen = 0; + var rdLenIndex = total; + total += 2; + + // RDATA + + record.data.split('.').forEach(funtion(label){ + txtLen += 1 + label.length; + + dv.setUint8(total, label.length, false); + total += 1; + + label.split('').forEach(function (ch) { + dv.setUint8(total, ch.charCodeAt(0), false); + total += 1; + }); + }); - // console.log("record data is: " + record.data); + dv.setUint16(rdLenIndex, record.data.length + 1, flase);s - // var txtLen = 0; - // var rdLenIndex = total; - // total += 2; - - // //RDATA - // // a sequence of labels - // record.data.split('.').forEach(function (label) { - // txtLen += 1 + label.length; - - // dv.setUint8(total, label.length, false); - // total += 1; - - // label.split('').forEach(function (ch) { - // dv.setUint8(total, ch.charCodeAt(0), false); - // total += 1; - // }); - // }); - - // // RDLENGTH - // dv.setUint16(rdLenIndex, record.data.length + 1, false); - - // return total; + return total; }; }('undefined' !== typeof window ? window : exports)); From 937e93d1df3137f6d149cfe071e2430487a6d996 Mon Sep 17 00:00:00 2001 From: westley Date: Sat, 18 Mar 2017 11:40:38 -0600 Subject: [PATCH 14/41] captured some txt records with dig.js --- test/txt_test/google.com.txt.0.bin | Bin 0 -> 212 bytes test/txt_test/google.com.txt.0.json | 201 ++++++++++++++++++++++++ test/txt_test/google.com.txt.query.bin | Bin 0 -> 28 bytes test/txt_test/google.com.txt.query.json | 19 +++ 4 files changed, 220 insertions(+) create mode 100644 test/txt_test/google.com.txt.0.bin create mode 100644 test/txt_test/google.com.txt.0.json create mode 100644 test/txt_test/google.com.txt.query.bin create mode 100644 test/txt_test/google.com.txt.query.json diff --git a/test/txt_test/google.com.txt.0.bin b/test/txt_test/google.com.txt.0.bin new file mode 100644 index 0000000000000000000000000000000000000000..f29c4a8c2c6319058bd8894aa85d89ff318fc31e GIT binary patch literal 212 zcmZQv*Vw?o2!t#QENtod`RO^S%*pw=3=9Gcj0bo?Bm)C?5rc|ynQd`FnxR5wUUE)p zN~%>nkf#SxuLo4GP?wmK160ohGRrxQfsHw@*!TbsnurO8h#`iE5m2NC>>}o8DGV$( h-Yak&=!5bjL3|~y0})VuK8UZvbs!7M&j#_;xB$dKGpPUo literal 0 HcmV?d00001 diff --git a/test/txt_test/google.com.txt.0.json b/test/txt_test/google.com.txt.0.json new file mode 100644 index 0000000..e50d47a --- /dev/null +++ b/test/txt_test/google.com.txt.0.json @@ -0,0 +1,201 @@ +{ + "header": { + "id": 430, + "qr": 1, + "opcode": 0, + "aa": 0, + "tc": 0, + "rd": 1, + "ra": 1, + "res1": 0, + "res2": 0, + "res3": 0, + "rcode": 0 + }, + "qdcount": 1, + "ancount": 1, + "nscount": 4, + "arcount": 4, + "question": [ + { + "name": "google.com", + "type": 16, + "typeName": "TXT", + "class": 1, + "className": "IN", + "byteLength": 16, + "labels": [ + "google", + "com" + ], + "cpcount": 0 + } + ], + "answer": [ + { + "name": "google.com", + "type": 16, + "typeName": "TXT", + "class": 1, + "className": "IN", + "byteLength": 48, + "labels": [ + "google", + "com" + ], + "cpcount": 1, + "rdstart": 40, + "rdlength": 36, + "ttl": 2930, + "data": [ + "v=spf1 include:_spf.google.com ~all" + ] + } + ], + "authority": [ + { + "name": "google.com", + "type": 2, + "typeName": "NS", + "class": 1, + "className": "IN", + "byteLength": 18, + "labels": [ + "google", + "com" + ], + "cpcount": 1, + "rdstart": 88, + "rdlength": 6, + "ttl": 82790, + "data": "ns3.google.com" + }, + { + "name": "google.com", + "type": 2, + "typeName": "NS", + "class": 1, + "className": "IN", + "byteLength": 18, + "labels": [ + "google", + "com" + ], + "cpcount": 1, + "rdstart": 106, + "rdlength": 6, + "ttl": 82790, + "data": "ns4.google.com" + }, + { + "name": "google.com", + "type": 2, + "typeName": "NS", + "class": 1, + "className": "IN", + "byteLength": 18, + "labels": [ + "google", + "com" + ], + "cpcount": 1, + "rdstart": 124, + "rdlength": 6, + "ttl": 82790, + "data": "ns1.google.com" + }, + { + "name": "google.com", + "type": 2, + "typeName": "NS", + "class": 1, + "className": "IN", + "byteLength": 18, + "labels": [ + "google", + "com" + ], + "cpcount": 1, + "rdstart": 142, + "rdlength": 6, + "ttl": 82790, + "data": "ns2.google.com" + } + ], + "edns_options": [], + "additional": [ + { + "name": "ns1.google.com", + "type": 1, + "typeName": "A", + "class": 1, + "className": "IN", + "byteLength": 16, + "labels": [ + "ns1", + "google", + "com" + ], + "cpcount": 2, + "rdstart": 160, + "rdlength": 4, + "ttl": 255588, + "address": "216.239.32.10" + }, + { + "name": "ns2.google.com", + "type": 1, + "typeName": "A", + "class": 1, + "className": "IN", + "byteLength": 16, + "labels": [ + "ns2", + "google", + "com" + ], + "cpcount": 2, + "rdstart": 176, + "rdlength": 4, + "ttl": 255577, + "address": "216.239.34.10" + }, + { + "name": "ns3.google.com", + "type": 1, + "typeName": "A", + "class": 1, + "className": "IN", + "byteLength": 16, + "labels": [ + "ns3", + "google", + "com" + ], + "cpcount": 2, + "rdstart": 192, + "rdlength": 4, + "ttl": 255599, + "address": "216.239.36.10" + }, + { + "name": "ns4.google.com", + "type": 1, + "typeName": "A", + "class": 1, + "className": "IN", + "byteLength": 16, + "labels": [ + "ns4", + "google", + "com" + ], + "cpcount": 2, + "rdstart": 208, + "rdlength": 4, + "ttl": 255595, + "address": "216.239.38.10" + } + ], + "byteLength": 212 +} \ No newline at end of file diff --git a/test/txt_test/google.com.txt.query.bin b/test/txt_test/google.com.txt.query.bin new file mode 100644 index 0000000000000000000000000000000000000000..393b3302b252400dbc495c75e1301f29ed6b5f86 GIT binary patch literal 28 fcmZQv$H>3{L?FPHo}ZtdlggZ&pUc1?z`zIqJ4OVE literal 0 HcmV?d00001 diff --git a/test/txt_test/google.com.txt.query.json b/test/txt_test/google.com.txt.query.json new file mode 100644 index 0000000..9361cf8 --- /dev/null +++ b/test/txt_test/google.com.txt.query.json @@ -0,0 +1,19 @@ +{ + "header": { + "id": 430, + "qr": 0, + "opcode": 0, + "aa": 0, + "tc": 0, + "rd": 1, + "ra": 0, + "rcode": 0 + }, + "question": [ + { + "name": "google.com", + "typeName": "TXT", + "className": "IN" + } + ] +} \ No newline at end of file From d00f83c625f5c05b7bea42f515d80c8929d1cf9c Mon Sep 17 00:00:00 2001 From: Daplie Date: Thu, 23 Mar 2017 17:33:55 -0600 Subject: [PATCH 15/41] finished TXT record type packer. --- packer/type.txt.js | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/packer/type.txt.js b/packer/type.txt.js index 93cfb4f..dee1b66 100644 --- a/packer/type.txt.js +++ b/packer/type.txt.js @@ -10,24 +10,32 @@ exports.DNS_PACKER_TYPE_TXT = function (ab, dv, total, record) { var txtLen = 0; var rdLenIndex = total; - total += 2; + total += 3; // RDATA + console.log("what is my record data: " + typeof record.data[0]); + console.log("what are my labels? "); + // var res = record.data[0].split(" "); + // console.log("Res: " + res); - record.data.split('.').forEach(funtion(label){ - txtLen += 1 + label.length; + console.log("for each rdata"); + record.data.forEach(function(str){ - dv.setUint8(total, label.length, false); + str.split('').forEach(function(ch){ + + + txtLen += 1; + // console.log(chcim); + dv.setUint8(total, ch.charCodeAt(0), false); total += 1; - - label.split('').forEach(function (ch) { - dv.setUint8(total, ch.charCodeAt(0), false); - total += 1; + }); }); - - dv.setUint16(rdLenIndex, record.data.length + 1, flase);s + console.log("txt rdata length is: " + txtLen); + dv.setUint16(rdLenIndex, txtLen+1, false); + dv.setUint8(rdLenIndex+2, txtLen, false); + // total +=1; return total; }; From 9b8526dc0621186bde5a798c6cf3f33341078fc5 Mon Sep 17 00:00:00 2001 From: Tim Caswell Date: Wed, 12 Apr 2017 12:21:33 -0500 Subject: [PATCH 16/41] Add missing dns type IDs to mapping table --- dns.types.js | 59 ++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 46 insertions(+), 13 deletions(-) diff --git a/dns.types.js b/dns.types.js index 015f438..b3aaa31 100644 --- a/dns.types.js +++ b/dns.types.js @@ -2,22 +2,55 @@ 'use strict'; var types = exports.DNS_TYPES = { - A: 0x01 // 1 -, NS: 0x02 // 2 -, CNAME: 0x05 // 5 -, SOA: 0x06 // 6 -, PTR: 0x0c // 12 -, MX: 0x0f // 15 -, TXT: 0x10 // 16 -, AAAA: 0x1c // 28 -, SRV: 0x21 // 33 -, OPT: 0x29 // 41 -, ANY: 0xff // 255 + A: 0x1 // 1 +, NS: 0x2 // 2 +, CNAME: 0x5 // 5 +, SOA: 0x6 // 6 +, NULL: 0xa // 10 +, PTR: 0xc // 12 +, HINFO: 0xd // 13 +, MX: 0xf // 15 +, TXT: 0x10 // 16 +, RP: 0x11 // 17 +, AFSDB: 0x12 // 18 +, SIG: 0x18 // 24 +, KEY: 0x19 // 25 +, AAAA: 0x1c // 28 +, LOC: 0x1d // 29 +, SRV: 0x21 // 33 +, NAPTR: 0x23 // 35 +, KX: 0x24 // 36 +, CERT: 0x25 // 37 +, DNAME: 0x27 // 39 +, OPT: 0x29 // 41 +, APL: 0x2a // 42 +, DS: 0x2b // 43 +, SSHFP: 0x2c // 44 +, IPSECKEY: 0x2d // 45 +, RRSIG: 0x2e // 46 +, NSEC: 0x2f // 47 +, DNSKEY: 0x30 // 48 +, DHCID: 0x31 // 49 +, NSEC3: 0x32 // 50 +, NSEC3PARAM: 0x33 // 51 +, TLSA: 0x34 // 52 +, HIP: 0x37 // 55 +, CDS: 0x3b // 59 +, CDNSKEY: 0x3c // 60 +, SPF: 0x63 // 99 +, TKEY: 0xf9 // 249 +, TSIG: 0xfa // 250 +, IXFR: 0xfb // 251 +, AXFR: 0xfc // 252 +, ANY: 0xff // 255 +, CAA: 0x101 // 257 +, TA: 0x8000 // 32768 +, DLV: 0x8001 // 32769 }; // and in reverse -Object.keys(types).forEach(function (key) { +for (var key in types) { types[types[key]] = key; -}); +} }('undefined' !== typeof window ? window : exports)); From e9a2794990c331bd51bcd75dfea069a47f3c2ee9 Mon Sep 17 00:00:00 2001 From: Tim Caswell Date: Wed, 12 Apr 2017 13:02:35 -0500 Subject: [PATCH 17/41] Add parser for CAA record --- parser/type.caa.js | 44 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 parser/type.caa.js diff --git a/parser/type.caa.js b/parser/type.caa.js new file mode 100644 index 0000000..fdc443f --- /dev/null +++ b/parser/type.caa.js @@ -0,0 +1,44 @@ +(function (exports) { +'use strict'; + +// A Certification Authority Authorization (CAA) record is used to specify which +// certificate authorities (CAs) are allowed to issue certificates for a domain. + +// Value Meaning/Use +// +// Flag An unsigned integer between 0-255. +// It is currently used to represent the critical flag, that has a +// specific meaning per RFC 6844 +// Tag An ASCII string that represents the identifier of the property +// represented by the record. +// Value The value associated with the tag. + +// The RFC currently defines 3 available tags: +// +// - issue: explicity authorizes a single certificate authority to issue a +// certificate (any type) for the hostname. +// - issuewild: explicity authorizes a single certificate authority to issue a +// wildcard certificate (and only wildcard) for the hostname. +// - iodef: specifies an URL to which a certificate authority may report +// policy violations. + +exports.DNS_PARSER_TYPE_CAA = function (ab, packet, record) { + + var data = new Uint8Array(ab); + var i = record.rdstart; + var flag = data[i++]; + var mid = data[i++]; + mid += i; + var end = record.rdstart + record.rdlength; + var tag = '', value = ''; + while (i < mid) { tag += String.fromCharCode(data[i++]); } + while (i < end) { value += String.fromCharCode(data[i++]); } + + record.flag = flag; + record.tag = tag; + record.value = value; + + return record; +}; + +}('undefined' !== typeof window ? window : exports)); From d5c20c58a344d0aa0a9e67a216528814ae700fef Mon Sep 17 00:00:00 2001 From: Tim Caswell Date: Thu, 13 Apr 2017 15:21:15 -0500 Subject: [PATCH 18/41] Bump version for new CAA parser and new type IDs --- README.md | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 0ab3647..3a6d494 100644 --- a/README.md +++ b/README.md @@ -180,7 +180,7 @@ the name of the type in the format `parser/type..js`. For example, if `CNAME` wasn't already supported and I wanted to add support for it I would follow these steps: -1) Update `dns.types.js` +1) Update `dns.types.js` if it's not there already. ``` A: 0x01 // 1 diff --git a/package.json b/package.json index 9f51fef..8932616 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "dns-suite", - "version": "1.0.3", + "version": "1.1.0", "description": "testing dns", "main": "dns.js", "scripts": { From 53cae83af4c13ca9be469ed46b11e7b1796671f9 Mon Sep 17 00:00:00 2001 From: tigerbot Date: Mon, 22 May 2017 14:14:18 -0600 Subject: [PATCH 19/41] changed examples to use `dns-suite` instead of `dns-js` --- dns.packer.js | 9 +++++- examples/cloud-respond.js | 63 +++++++++++++++++++++++---------------- examples/dns_test.js | 3 +- examples/listen.js | 11 +++---- packer/type.srv.js | 6 ++-- parser/type.soa.js | 8 ++--- 6 files changed, 58 insertions(+), 42 deletions(-) diff --git a/dns.packer.js b/dns.packer.js index 594283c..61f876a 100644 --- a/dns.packer.js +++ b/dns.packer.js @@ -37,6 +37,11 @@ var dnspack = exports.DNS_PACKER = { if (!r.className) { throw new Error("no className"); } + if (!classes[r.className]) { + console.warn("ignoring invalid class '" + r.className + "' for '" + r.name); + } else { + r.class = classes[r.className]; + } } if (!r.type) { @@ -44,7 +49,9 @@ var dnspack = exports.DNS_PACKER = { throw new Error("no typeName"); } if (!types[r.typeName]) { - console.warn("ignoring invalid type '" + r.type + "' for '" + r.name + "', ignoring"); + console.warn("ignoring invalid type '" + r.typeName + "' for '" + r.name); + } else { + r.type = types[r.typeName]; } } } diff --git a/examples/cloud-respond.js b/examples/cloud-respond.js index 97d440d..7fe5957 100644 --- a/examples/cloud-respond.js +++ b/examples/cloud-respond.js @@ -1,20 +1,44 @@ 'use strict'; module.exports.respond = function (socket, packets, rinfo) { - var dns = require('dns-js'); + var dns = require('../'); var os = require('os'); var queryname = '_cloud._tcp.local'; console.log(packets); packets.forEach(function (packet) { + // Only respond to queries, otherwise we'll end up responding to ourselves forever. + if (packet.header.qr !== 0) { + return; + } + packet.question.forEach(function (q) { if (queryname !== q.name) { return; } console.log('question', q.name, q.typeName, q.className, q.flag, q); - var rpacket = new dns.DNSPacket(); + var rpacket = { + header: { + id: packet.header.id + , qr: 1 + , opcode: 0 + , aa: 1 + , tc: 0 + , rd: 0 + , ra: 0 + , res1: 0 + , res2: 0 + , res3: 0 + , rcode: 0 + , } + , question: [q] + , answer: [] + , authority: [] + , additional: [] + , edns_options: [] + }; var ifaces = os.networkInterfaces(); //var llRe = /^(fe80|169)/i; // link-local @@ -29,9 +53,9 @@ module.exports.respond = function (socket, packets, rinfo) { iface.forEach(function (pface) { rpacket.additional.push({ name: q.name - , type: ('IPv4' === pface.family ? dns.DNSRecord.Type.A : dns.DNSRecord.Type.AAAA) + , typeName: ('IPv4' === pface.family ? 'A' : 'AAAA') , ttl: 10 - , class: dns.DNSRecord.Class.IN + , className: 'IN' , address: pface.address // '_workstation._tcp.local' }); }); @@ -40,43 +64,33 @@ module.exports.respond = function (socket, packets, rinfo) { var myRndId = 'be1af7a'; rpacket.answer.push({ name: q.name - , type: dns.DNSRecord.Type.PTR + , typeName: 'PTR' , ttl: 10 - , class: dns.DNSRecord.Class.IN + , className: 'IN' , data: myRndId + '.' + queryname }); - rpacket.question.push(new dns.DNSRecord( - queryname // Name - , dns.DNSRecord.Type.PTR // Type - , dns.DNSRecord.Class.IN // Class - //, null // TTL - )); rpacket.additional.push({ name: myRndId + '.' + queryname - , type: dns.DNSRecord.Type.SRV + , typeName: 'SRV' , ttl: 10 - , class: dns.DNSRecord.Class.IN - , priority: 0 + , className: 'IN' + , priority: 1 , weight: 0 , port: 443 - , target: myRndId + ".local" + , target: myRndId + ".local" }); rpacket.additional.push({ name: myRndId + '.' + '_device-info._tcp.local' - , type: dns.DNSRecord.Type.TXT + , typeName: 'TXT' , ttl: 10 - , class: dns.DNSRecord.Class.IN + , className: 'IN' , data: ["model=CloudHome1,1", "dappsvers=1"] }); - rpacket.header.id = packet.header.id; - rpacket.header.aa = 1; - rpacket.header.qr = 1; - rpacket.header.rd = 0; console.log(''); console.log('START JSON PACKET'); console.log(rpacket); - var buf = dns.DNSPacket.toBuffer(rpacket); + var buf = dns.DNSPacket.write(rpacket); console.log(buf.toString('hex')); console.log('END JSON PACKET'); console.log(''); @@ -89,8 +103,7 @@ module.exports.respond = function (socket, packets, rinfo) { console.log(''); socket.send(buf, rinfo.port, rinfo.address); }); - /* - */ + packet.answer.forEach(function (a) { console.log('answer', a.name, a.typeName, a.className, a.flag, a); }); diff --git a/examples/dns_test.js b/examples/dns_test.js index acba7a9..6efa30c 100644 --- a/examples/dns_test.js +++ b/examples/dns_test.js @@ -1,7 +1,6 @@ 'use strict'; var dgram = require('dgram'); -var dnsjs = require('dns-js'); // SO_REUSEADDR and SO_REUSEPORT are set because // the system mDNS Responder may already be listening on this port @@ -22,4 +21,4 @@ socket.bind(port, function () { socket.addMembership(broadcast); // ... more stuff -}); \ No newline at end of file +}); diff --git a/examples/listen.js b/examples/listen.js index cc12267..a3c8821 100644 --- a/examples/listen.js +++ b/examples/listen.js @@ -5,7 +5,7 @@ var socket = dgram.createSocket({ type: 'udp4' , reuseAddr: true }); -var dns = require('dns-js'); +var dns = require('../'); //var DNSPacket = dns.DNSPacket; var broadcast = '224.0.0.251'; // mdns @@ -31,17 +31,14 @@ return binString; } socket.on('message', function (message, rinfo) { - console.log('Received %d bytes from %s:%d\n', - message.length, rinfo.address, rinfo.port); + console.log('Received %d bytes from %s:%d', message.length, rinfo.address, rinfo.port); //console.log(msg.toString('utf8')); message.forEach(function(byte){ - - console.log(pad(byte.toString(2), 8,'0')); - + console.log(pad(byte.toString(2), 8, '0')); }); - + // console.log(message.toString('hex')); // console.log(message.toString('ascii')); var packets; diff --git a/packer/type.srv.js b/packer/type.srv.js index dee2731..063576f 100644 --- a/packer/type.srv.js +++ b/packer/type.srv.js @@ -3,7 +3,7 @@ // SRV RDATA contains: // Priority: The relative priority of this service. 16-bit (range 0-65535) -// Weight: Used when more than one serivice has the same priority. 16-bit +// Weight: Used when more than one serivice has the same priority. 16-bit // (range 0-65535) // Port: Port number assigned to the symbolic service. 16-bit (range 0-65535) // Target: The name of the host that will provide service. @@ -31,7 +31,7 @@ exports.DNS_PACKER_TYPE_SRV = function (ab, dv, total, record) { // console.log("record port is: " + record.port); // console.log("record target is: " + record.target); // console.log("total length currently is: " + total); - + var srvLen = 6; // 16-bit priority, weight and port = 6 Bytes var rdLenIndex = total; @@ -62,7 +62,7 @@ exports.DNS_PACKER_TYPE_SRV = function (ab, dv, total, record) { // RDLENGTH dv.setUint16(rdLenIndex, srvLen, false); - + return total; }; diff --git a/parser/type.soa.js b/parser/type.soa.js index 534197a..2ca64ff 100644 --- a/parser/type.soa.js +++ b/parser/type.soa.js @@ -24,12 +24,12 @@ exports.DNS_PARSER_TYPE_SOA = function (ab, packet, record) { // Primary NS record.name_server = unpackLabels(new Uint8Array(ab), record.rdstart, { byteLength: 0, cpcount: 0, labels: [], name: '' }).name; - + // if there exists compression pointers in the rdata if (cpcount > 0){ // do something awesome with compression pointers to get the email address // I need the length of all the data before the email address starts. - // if there are compression pointers then there will be a byte to indicate the length of each label, the label, + // if there are compression pointers then there will be a byte to indicate the length of each label, the label, // then there will be a compression pointer to grab the longest label. var start = 2; // start or email_addr. take into account compression pointer and address length @@ -41,7 +41,7 @@ exports.DNS_PARSER_TYPE_SOA = function (ab, packet, record) { if(parseInt(dv.getUint8(start - 2), 10) === 192){ record.email_addr = unpackLabels(new Uint8Array(ab), record.rdstart + start ,{ byteLength: 0, cpcount: 0, labels: [], name: '' }).name; } - } + } } // if there are no compression pointers, we can get the email address directly from the offset else { @@ -57,7 +57,7 @@ exports.DNS_PARSER_TYPE_SOA = function (ab, packet, record) { record.ex = dv.getUint32(dv.byteLength - 8, false); // Minimum TTL record.nx = dv.getUint32(dv.byteLength - 4, false); - + return record; From 8960b9ae2a3278fec51cf39359573ad94ae7155b Mon Sep 17 00:00:00 2001 From: tigerbot Date: Mon, 22 May 2017 15:05:48 -0600 Subject: [PATCH 20/41] added random ID to all aditional record responses --- examples/cloud-respond.js | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/examples/cloud-respond.js b/examples/cloud-respond.js index 7fe5957..bd983c4 100644 --- a/examples/cloud-respond.js +++ b/examples/cloud-respond.js @@ -39,9 +39,19 @@ module.exports.respond = function (socket, packets, rinfo) { , additional: [] , edns_options: [] }; + + var myRndId = 'be1af7a'; + + rpacket.answer.push({ + name: q.name + , typeName: 'PTR' + , ttl: 10 + , className: 'IN' + , data: myRndId + '.' + queryname + }); + var ifaces = os.networkInterfaces(); //var llRe = /^(fe80|169)/i; // link-local - Object.keys(ifaces).forEach(function (iname) { var iface = ifaces[iname]; @@ -52,7 +62,7 @@ module.exports.respond = function (socket, packets, rinfo) { iface.forEach(function (pface) { rpacket.additional.push({ - name: q.name + name: myRndId + '.' + q.name , typeName: ('IPv4' === pface.family ? 'A' : 'AAAA') , ttl: 10 , className: 'IN' @@ -61,14 +71,6 @@ module.exports.respond = function (socket, packets, rinfo) { }); }); - var myRndId = 'be1af7a'; - rpacket.answer.push({ - name: q.name - , typeName: 'PTR' - , ttl: 10 - , className: 'IN' - , data: myRndId + '.' + queryname - }); rpacket.additional.push({ name: myRndId + '.' + queryname , typeName: 'SRV' From f8cf8aef77e6f3f093178269dd8f145603eeee40 Mon Sep 17 00:00:00 2001 From: tigerbot Date: Mon, 22 May 2017 18:22:54 -0600 Subject: [PATCH 21/41] added shortening of unpacked string IPv6 addresses --- parser/type.aaaa.js | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/parser/type.aaaa.js b/parser/type.aaaa.js index 9a05653..e05f20b 100644 --- a/parser/type.aaaa.js +++ b/parser/type.aaaa.js @@ -27,6 +27,20 @@ exports.DNS_PARSER_TYPE_AAAA = function (ab, packet, record) { s += dv.getUint16(i, false).toString(16); } + // Represent the string address as recommended on the wikipedia page + // https://en.wikipedia.org/wiki/IPv6_address#Recommended_representation_as_text. + // (shorten the longest section of 0's as long as it's more than one section, replacing + // the left-most instance in the event of ties.) + var re = /:(0:)+/g; + var match; + var longest = '_BAD'; + while (!!(match = re.exec(s))) { + if (match[0].length > longest.length) { + longest = match[0]; + } + } + s = s.replace(longest, '::'); + record.address = s; return record; }; From a137d6b9377512fe8e062a1d5f5b91fa4f1031db Mon Sep 17 00:00:00 2001 From: tigerbot Date: Tue, 23 May 2017 15:58:32 -0600 Subject: [PATCH 22/41] limited how often we log about unsupported features --- dns.js | 10 +++++++++- dns.parser.js | 18 +++++++++++------- 2 files changed, 20 insertions(+), 8 deletions(-) diff --git a/dns.js b/dns.js index aab2e2b..902e37b 100644 --- a/dns.js +++ b/dns.js @@ -5,6 +5,8 @@ var Parser = (exports.DNS_PARSER || require('./dns.parser.js').DNS_PARSER); var Packer = (exports.DNS_PACKER || require('./dns.packer.js').DNS_PACKER); //var classes = exports.DNS_CLASSES || require('./dns.classes.js').DNS_CLASSES; //var types = exports.DNS_TYPES || require('./dns.types.js').DNS_TYPES; +var logged = {}; + exports.DNSPacket = { parse: function (nb) { // backwards compat with node buffer @@ -21,8 +23,14 @@ exports.DNSPacket = { record = Parser.unpackRdata(ab, packet, record); } catch (e) { - console.error('[Error] unpackRdata: ' + e.message); record.error = e; + if (!/^support for dns/i.test(e.message)) { + console.error('[Error] unpackRdata: ' + e.message); + } + else if (!logged[e.message]) { + console.error('[Error] unpackRdata: ' + e.message); + logged[e.message] = true; + } } } diff --git a/dns.parser.js b/dns.parser.js index 4773bbf..62bf578 100644 --- a/dns.parser.js +++ b/dns.parser.js @@ -31,13 +31,17 @@ pdns.unpackHeader = function (i) { pdns._unpackLabels = exports.DNS_UNPACK_LABELS || require('./dns.unpack-labels.js').DNS_UNPACK_LABELS; +var optWarned = false; pdns.unpackOpt = function (ab, packet, rec) { var dv; // https://tools.ietf.org/html/rfc6891#section-6 - console.log('OPT is not yet supported'); + if (!optWarned) { + console.warn('OPT is not yet supported'); + optWarned = true; + } if ('undefined' !== typeof packet.edns_version) { - console.warn("More that one OPT, should respond with FORMERR, but not implmentede"); + console.warn("More that one OPT, should respond with FORMERR, but not implemented"); } if (packet.name) { console.warn("name '" + packet.name + "' should not exist for type OPT 0x29 41"); @@ -60,11 +64,11 @@ pdns.unpackOpt = function (ab, packet, rec) { packet.edns_version = dv.getUint8(1, false); packet.do = dv.getUint8(2, false) & 0x8000; // 1000 0000 packet.z = dv.getUint16(2, false) & 0x7FFF; // 0111 1111 - /* -"edns_options": [], -"payload": 4096, -"edns_version": 0, -"do": 0 + /* + "edns_options": [], + "payload": 4096, + "edns_version": 0, + "do": 0 */ }; pdns.unpack = function (ab) { From a295f9c3e70dc71304305a5e1264ea4c2d36b31e Mon Sep 17 00:00:00 2001 From: tigerbot Date: Tue, 23 May 2017 16:15:08 -0600 Subject: [PATCH 23/41] v1.1.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 8932616..093be61 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "dns-suite", - "version": "1.1.0", + "version": "1.1.1", "description": "testing dns", "main": "dns.js", "scripts": { From a09dd27c7d24225a81da5f2b5bf04576144bc9f1 Mon Sep 17 00:00:00 2001 From: tigerbot Date: Tue, 30 May 2017 16:18:48 -0600 Subject: [PATCH 24/41] fixed a bug in message compression pointer handling --- dns.unpack-labels.js | 26 ++++++------ test/fixtures/canone30522.local.bin | Bin 0 -> 556 bytes test/fixtures/canone30522.local.js | 59 ++++++++++++++++++++++++++++ 3 files changed, 73 insertions(+), 12 deletions(-) create mode 100644 test/fixtures/canone30522.local.bin create mode 100644 test/fixtures/canone30522.local.js diff --git a/dns.unpack-labels.js b/dns.unpack-labels.js index ca791e2..0956fc0 100644 --- a/dns.unpack-labels.js +++ b/dns.unpack-labels.js @@ -29,18 +29,19 @@ exports.DNS_UNPACK_LABELS = function (ui8, ptr, q) { break; } - if (0xc0 === len) { - var cpptr = ui8[total + 1]; + // Handle message compression pointers. See 4.1.4 of RFC1035 for details. + if (len >= 0xc0) { + var cpptr = ((ui8[total] & 0x3f) << 8) | ui8[total + 1]; - // we're not coming back! - ptr = cpptr; + // We're not coming back, so if this is the first time we're following one of + // these pointers we up the byteLength to mark the pointer as part of the label if (!q.cpcount) { q.byteLength += 2; // cp and len } q.cpcount += 1; // recursion - return exports.DNS_UNPACK_LABELS(ui8, ptr, q); + return exports.DNS_UNPACK_LABELS(ui8, cpptr, q); } //str.length = 0; // fast empty array @@ -51,27 +52,28 @@ exports.DNS_UNPACK_LABELS = function (ui8, ptr, q) { ); } + // Advance the pointer to after the length indicator, then read the string in. + total += 1; for (i = 0; i < len; i += 1) { - total += 1; // TODO check url-allowable characters label.push(String.fromCharCode(ui8[total])); + total += 1; } if (label.length) { q.labels.push(label.join('')); } - total += 1; - + // It is important this be done every time, so that if we run into a message compression + // pointer later we still have a record of what was consumed before that. + if (0 === q.cpcount) { + q.byteLength = total - ptr; + } } while (0 !== len && undefined !== len); //str.pop(); // remove trailing '.' q.name = q.labels.join('.'); - if (0 === q.cpcount) { - q.byteLength = total - ptr; - } - return q; }; diff --git a/test/fixtures/canone30522.local.bin b/test/fixtures/canone30522.local.bin new file mode 100644 index 0000000000000000000000000000000000000000..0fccbcf0531f4ae8fbecbed7f6e4d13eb86609d2 GIT binary patch literal 556 zcmZuv+iDvz5S5G9wMk4{N&|sDB=n_u*z6^)aS8)z)~G4e#o*1ene58-Qdv^8v&DHz zJ|G{G&)7dp<#k&cs6b-oFlWwO#Mm8kr{%8qVs3Kj=SWzR6}W28DKnnb8A`@>o0vzo z_c}qP)xm@h<1jgx30sJ=-rZ?XaT0!rFBL%2GAH; zWJrZpfzC*fzilnRd{wB*N>~z^k3sNH`NvJi0T$NDD>`1%O7^SrYChqgwi+#4D-Qa5oW?4UPX}~ xMfu1dg>mRF2BYZYbi1L>EJFpU#~qv37cBU*9%r}Dm|I)?7wb9OWA2-r{Q@klre^>E literal 0 HcmV?d00001 diff --git a/test/fixtures/canone30522.local.js b/test/fixtures/canone30522.local.js new file mode 100644 index 0000000..169ca3f --- /dev/null +++ b/test/fixtures/canone30522.local.js @@ -0,0 +1,59 @@ +module.exports = { + "header": { + "id": 0, + "qr": 1, + "opcode": 0, + "aa": 0, + "tc": 0, + "rd": 0, + "ra": 0, + "res1": 0, + "res2": 0, + "res3": 0, + "rcode": 0 + }, + "question": [], + "answer": [ + { + "name": "_pdl-datastream._tcp.local", + "type": 12, + "class": 1, + "ttl": 255, + "data": "Canon MF620C Series._pdl-datastream._tcp.local" + } + ], + "additional": [ + { + "name": "Canone30522.local", + "type": 1, + "class": 32769, + "ttl": 255, + }, + { + "name": "Canon MF620C Series._pdl-datastream._tcp.local", + "type": 33, + "class": 32769, + "ttl": 255, + }, + { + "name": "Canon MF620C Series._pdl-datastream._tcp.local", + "type": 16, + "class": 32769, + "ttl": 255, + }, + { + "name": "Canone30522.local", + "type": 47, + "class": 32769, + "ttl": 255, + }, + { + "name": "Canon MF620C Series._pdl-datastream._tcp.local", + "type": 47, + "class": 32769, + "ttl": 255, + } + ], + "authority": [], + "edns_options": [] +}; From 950867c452323da776c050363b22d8f06a8ed414 Mon Sep 17 00:00:00 2001 From: tigerbot Date: Tue, 30 May 2017 16:33:14 -0600 Subject: [PATCH 25/41] v1.1.2 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 093be61..8a8e44a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "dns-suite", - "version": "1.1.1", + "version": "1.1.2", "description": "testing dns", "main": "dns.js", "scripts": { From 8d1cb165ae23eedbb2659039c41e2c5be7e007f0 Mon Sep 17 00:00:00 2001 From: Jim Hager Date: Tue, 15 Aug 2017 15:10:39 -0600 Subject: [PATCH 26/41] Add new file --- examples/test-output | 114 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 114 insertions(+) create mode 100644 examples/test-output diff --git a/examples/test-output b/examples/test-output new file mode 100644 index 0000000..d5c8d17 --- /dev/null +++ b/examples/test-output @@ -0,0 +1,114 @@ +I created a subdomain for `daplie.pe` named `delegated.daplie.pe`. + +Below are the results of the `whois`, `dig`, and `dig.js` commands. + +============================ + +Users-MBP:~ jim$ whois daplie.pe +Domain Name: daplie.pe +WHOIS Server: NIC .PE +Sponsoring Registrar: 1API GmbH +Domain Status: clientTransferProhibited +Domain Status: clientUpdateProhibited +Domain Status: clientDeleteProhibited +Domain Status: clientRenewProhibited +Registrant Name: Daplie Labs +Admin Name: Daplie Labs +Admin Email: domains@daplie.com +Name Server: ns27.domaincontrol.com +Name Server: ns28.domaincontrol.com +DNSSEC: unsigned +>>> Last update of WHOIS database: 2017-08-15T19:49:36.243Z <<< + + +================================ + +Users-MBP:~ jim$ dig delegated.daplie.pe @ns27.domaincontrol.com + +; <<>> DiG 9.8.3-P1 <<>> delegated.daplie.pe @ns27.domaincontrol.com +;; global options: +cmd +;; Got answer: +;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 37275 +;; flags: qr aa rd; QUERY: 1, ANSWER: 1, AUTHORITY: 2, ADDITIONAL: 0 +;; WARNING: recursion requested but not available + +;; QUESTION SECTION: +;delegated.daplie.pe. IN A + +;; ANSWER SECTION: +delegated.daplie.pe. 600 IN A 50.63.202.28 + +;; AUTHORITY SECTION: +daplie.pe. 3600 IN NS ns28.domaincontrol.com. +daplie.pe. 3600 IN NS ns27.domaincontrol.com. + +;; Query time: 29 msec +;; SERVER: 216.69.185.14#53(216.69.185.14) +;; WHEN: Tue Aug 15 13:54:23 2017 +;; MSG SIZE rcvd: 108 + +=================================== + +Finding JSON information through dig -- used website `dig.jsondns.org` with the query format (URL) +`dig.jsondns.org/IN/delegated.daplie.pe/A` : + +{ + "header": { + "id": 59404, + "qr": true, + "opcode": "Query", + "aa": false, + "ad": false, + "tc": false, + "rd": true, + "ra": true, + "cd": true, + "rcode": "NOERROR", + "qdcount": 1, + "nscount": 0, + "ancount": 1, + "arcount": 0 + }, + "question": [ + { + "qname": "delegated.daplie.pe", + "qtype": "A", + "qclass": "IN" + } + ], + "answer": [ + { + "name": "delegated.daplie.pe", + "type": "A", + "class": "IN", + "ttl": 600, + "rdata": "184.168.221.5" + } + ], + "authority": [ + + ], + "additional": [ + + ] +} + + +================================================== + +Output from `dig.js delegated.daplie.pe`: + +Users-MBP:dig.js jim$ dig.js delegated.daplie.pe + +; <<>> dig.js v0.0.0 <<>> delegated.daplie.pe +;; Got answer: +;; ->>HEADER<<- +{"id":24943,"qr":1,"opcode":0,"aa":0,"tc":0,"rd":1,"ra":1,"res1":0,"res2":0,"res3":0,"rcode":0} + +;; QUESTION SECTION: +;delegated.daplie.pe. IN ANY + +;; ANSWER SECTION: +;delegated.daplie.pe. 599 IN A 50.63.202.18 + +;; MSG SIZE rcvd: 53 \ No newline at end of file From 12093c52d3c9b63b256f6d34b4c4d80f21b171dd Mon Sep 17 00:00:00 2001 From: AJ ONeal Date: Mon, 25 Sep 2017 15:57:40 -0600 Subject: [PATCH 27/41] remove logs --- packer/type.txt.js | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/packer/type.txt.js b/packer/type.txt.js index dee1b66..e63c36e 100644 --- a/packer/type.txt.js +++ b/packer/type.txt.js @@ -13,26 +13,18 @@ exports.DNS_PACKER_TYPE_TXT = function (ab, dv, total, record) { total += 3; // RDATA - console.log("what is my record data: " + typeof record.data[0]); - console.log("what are my labels? "); - // var res = record.data[0].split(" "); - // console.log("Res: " + res); - - console.log("for each rdata"); record.data.forEach(function(str){ str.split('').forEach(function(ch){ - txtLen += 1; // console.log(chcim); dv.setUint8(total, ch.charCodeAt(0), false); total += 1; - + }); }); - console.log("txt rdata length is: " + txtLen); dv.setUint16(rdLenIndex, txtLen+1, false); dv.setUint8(rdLenIndex+2, txtLen, false); // total +=1; From 0567aa31c88f6ba39193c7e74a6003cccc4a18e0 Mon Sep 17 00:00:00 2001 From: AJ ONeal Date: Mon, 25 Sep 2017 16:48:09 -0600 Subject: [PATCH 28/41] add nxdomain response --- test/soa_test/yahoo.com.nx.json | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 test/soa_test/yahoo.com.nx.json diff --git a/test/soa_test/yahoo.com.nx.json b/test/soa_test/yahoo.com.nx.json new file mode 100644 index 0000000..250ca5f --- /dev/null +++ b/test/soa_test/yahoo.com.nx.json @@ -0,0 +1,17 @@ +{ "header": + { "id":19900,"qr":1,"opcode":0,"aa":0,"tc":0,"rd":1,"ra":1,"res1":0,"res2":0,"res3":0,"rcode":3}, + "qdcount":1, + "ancount":0, + "nscount":1, + "arcount":0, + "question":[ + {"name":"snthaouesnthaouensth.yahoo.com","type":255,"typeName":"ANY","class":1,"className":"IN","byteLength":36,"labels":["snthaouesnthaouensth","yahoo","com"],"cpcount":0} + ], + "answer":[], + "authority":[ + {"name":"yahoo.com","type":6,"typeName":"SOA","class":1,"className":"IN","byteLength":61,"labels":["yahoo","com"],"cpcount":1,"rdstart":60,"rdlength":49,"ttl":599,"name_server":"ns1.yahoo.com","email_addr":"hostmaster.yahoo-inc.com","sn":2017092539,"ref":3600,"ret":300,"ex":1814400,"nx":600} + ], + "edns_options":[], + "additional":[], + "byteLength":109 +} From f992b37800d45b236027479e1da2c1709cb031ba Mon Sep 17 00:00:00 2001 From: AJ ONeal Date: Mon, 25 Sep 2017 17:10:50 -0600 Subject: [PATCH 29/41] add nx soa record --- test/soa_test/nx.yahoo.com.any.0.bin | Bin 0 -> 109 bytes test/soa_test/nx.yahoo.com.any.0.hex | 8 +++ test/soa_test/nx.yahoo.com.any.0.json | 64 ++++++++++++++++++++++ test/soa_test/nx.yahoo.com.any.query.bin | Bin 0 -> 48 bytes test/soa_test/nx.yahoo.com.any.query.hex | 4 ++ test/soa_test/nx.yahoo.com.any.query.json | 21 +++++++ 6 files changed, 97 insertions(+) create mode 100644 test/soa_test/nx.yahoo.com.any.0.bin create mode 100644 test/soa_test/nx.yahoo.com.any.0.hex create mode 100644 test/soa_test/nx.yahoo.com.any.0.json create mode 100644 test/soa_test/nx.yahoo.com.any.query.bin create mode 100644 test/soa_test/nx.yahoo.com.any.query.hex create mode 100644 test/soa_test/nx.yahoo.com.any.query.json diff --git a/test/soa_test/nx.yahoo.com.any.0.bin b/test/soa_test/nx.yahoo.com.any.0.bin new file mode 100644 index 0000000000000000000000000000000000000000..b7c923902dea05f14c4b90cde1e41be0dfb30be6 GIT binary patch literal 109 zcmX@e-Pp{)$iM)?BE@+n8HxF&sW3XPxFmzMGBG1RpE)@{mx19w1LFZj1~!mdrf>#B x=DcFV1BzT3`NbuOm|vO-qw|VOGFU4UGxGD9lk;;K82&Rb0stu>4b=bu literal 0 HcmV?d00001 diff --git a/test/soa_test/nx.yahoo.com.any.query.hex b/test/soa_test/nx.yahoo.com.any.query.hex new file mode 100644 index 0000000..89a79a1 --- /dev/null +++ b/test/soa_test/nx.yahoo.com.any.query.hex @@ -0,0 +1,4 @@ +0000000 c1 0b 01 00 00 01 00 00 00 00 00 00 14 73 6e 74 +0000010 68 61 6f 75 65 73 6e 74 68 61 6f 75 65 6e 73 74 +0000020 68 05 79 61 68 6f 6f 03 63 6f 6d 00 00 ff 00 01 +0000030 diff --git a/test/soa_test/nx.yahoo.com.any.query.json b/test/soa_test/nx.yahoo.com.any.query.json new file mode 100644 index 0000000..043baff --- /dev/null +++ b/test/soa_test/nx.yahoo.com.any.query.json @@ -0,0 +1,21 @@ +{ + "header": { + "id": 49419, + "qr": 0, + "opcode": 0, + "aa": 0, + "tc": 0, + "rd": 1, + "ra": 0, + "rcode": 0 + }, + "question": [ + { + "name": "snthaouesnthaouensth.yahoo.com", + "typeName": "ANY", + "className": "IN", + "class": 1, + "type": 255 + } + ] +} \ No newline at end of file From 8f09c4f4d3167d28ef434dc6367df55bc8bae013 Mon Sep 17 00:00:00 2001 From: AJ ONeal Date: Mon, 25 Sep 2017 18:12:14 -0600 Subject: [PATCH 30/41] add bluebird as dev dep --- package.json | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index 8a8e44a..4000ccf 100644 --- a/package.json +++ b/package.json @@ -11,5 +11,8 @@ "url": "git@git.daplie.com:Daplie/dns-suite.git" }, "author": "", - "license": "(MIT or Apache2)" + "license": "(MIT or Apache2)", + "developmentDependencies": { + "bluebird": "^3.5.0" + } } From ab533ab36c2e8ca40b432645dce899db9d1f61f8 Mon Sep 17 00:00:00 2001 From: AJ ONeal Date: Mon, 25 Sep 2017 18:20:32 -0600 Subject: [PATCH 31/41] WIP dns-pack --- bin/dns-pack.js | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 bin/dns-pack.js diff --git a/bin/dns-pack.js b/bin/dns-pack.js new file mode 100644 index 0000000..b1d08b1 --- /dev/null +++ b/bin/dns-pack.js @@ -0,0 +1,41 @@ +'use strict'; + +// EXAMPLE: +// node bin/dns-parse.js samples/a-0.mdns.bin + +// pass a terminal arg +var filename = process.argv[2]; +if (!filename) { + console.error("Usage: node bin/dns-pack.js "); + console.error("Example: node bin/dns-pack.js ./samples/services-0.mdns.json"); + process.exit(1); +} + + +var PromiseA = require('bluebird'); +var fs = PromiseA.promisifyAll(require('fs')); +var dnsjs = require('../').DNSPacket; + +fs.readFileAsync(filename, null).then(function (nb) { + // + // current reference impl + // + //console.log(require('native-dns-packet').parse(nb)); + + + // + // other reference impl + // + //console.log(require('dns-js').DNSPacket.parse(nb)); + + // nb is a Uint8Array (ArrayBufferView) for nb.buffer + // nb.buffer is the actual ArrayBuffer + + //var ab = nb.buffer.slice(nb.byteOffset, nb.byteOffset + nb.byteLength); + var packet = dnsjs.write(JSON.parse(buffer.toString('ascii'))); + + //console.log('[packet]', nb.byteLength, 'bytes:'); + //console.log(JSON.stringify(packet, null, 2)); + + //TODO hexdump packet +}); From e9169d7ef16d37b46b7d8d6bec2b7b70664d96ef Mon Sep 17 00:00:00 2001 From: AJ ONeal Date: Tue, 26 Sep 2017 15:58:38 -0600 Subject: [PATCH 32/41] dns-pack works for json files --- bin/dns-pack.js | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/bin/dns-pack.js b/bin/dns-pack.js index b1d08b1..ddb6973 100644 --- a/bin/dns-pack.js +++ b/bin/dns-pack.js @@ -3,12 +3,22 @@ // EXAMPLE: // node bin/dns-parse.js samples/a-0.mdns.bin +var path = require('path'); // pass a terminal arg var filename = process.argv[2]; +var outname = process.argv[3]; if (!filename) { - console.error("Usage: node bin/dns-pack.js "); - console.error("Example: node bin/dns-pack.js ./samples/services-0.mdns.json"); + console.error("Usage: node bin/dns-pack.js "); + console.error("Example: node bin/dns-pack.js ./samples/services-0.mdns.json ./services-0.mdns.bin"); process.exit(1); + return; +} +if (!outname) { + console.warn(''); + console.warn( + "Usage: node bin/dns-pack.js '" + filename + "' './" + path.basename(filename).replace(path.extname(filename), '') + ".bin'" + ); + console.warn(''); } @@ -32,10 +42,20 @@ fs.readFileAsync(filename, null).then(function (nb) { // nb.buffer is the actual ArrayBuffer //var ab = nb.buffer.slice(nb.byteOffset, nb.byteOffset + nb.byteLength); - var packet = dnsjs.write(JSON.parse(buffer.toString('ascii'))); + var packet = dnsjs.write(JSON.parse(nb.toString('ascii'))); //console.log('[packet]', nb.byteLength, 'bytes:'); //console.log(JSON.stringify(packet, null, 2)); //TODO hexdump packet + var hexdump = require('hexdump.js').hexdump; + var str = hexdump(packet); + + console.log(str); + + if (outname) { + fs.writeFileSync(outname, packet, null); + console.log(''); + console.log("wrote '" + outname + "'"); + } }); From e0af1007c7513cdaee7b2e268bd6dfc085119359 Mon Sep 17 00:00:00 2001 From: AJ ONeal Date: Tue, 26 Sep 2017 18:26:20 -0600 Subject: [PATCH 33/41] WIP self-test on a bin or json file --- bin/dns-test.js | 86 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 86 insertions(+) create mode 100644 bin/dns-test.js diff --git a/bin/dns-test.js b/bin/dns-test.js new file mode 100644 index 0000000..6fc2aef --- /dev/null +++ b/bin/dns-test.js @@ -0,0 +1,86 @@ +'use strict'; + +// EXAMPLE: +// node bin/dns-parse.js samples/a-0.mdns.bin + +var path = require('path'); +// pass a terminal arg +var filename = process.argv[2]; +var outname = process.argv[3]; + +if (!filename || /(-h)|(--help)/.test(process.argv.join(' '))) { + console.error(""); + console.error("Accepts a DNS packet (binary or json), converts it, and then converts it back to verify the function of the parser and packer"); + console.error(""); + console.error("Usage: node bin/dns-test.js "); + console.error("Example: node bin/dns-test.js ./samples/services-0.mdns.json"); + process.exit(1); + return; +} + +if (!outname) { + console.warn(''); + console.warn( + "Usage: node bin/dns-pack.js '" + filename + "' './" + path.basename(filename).replace(path.extname(filename), '') + ".bin'" + ); + console.warn(''); +} + +var PromiseA = require('bluebird'); +var fs = PromiseA.promisifyAll(require('fs')); +var dnsjs = require('../').DNSPacket; +var extname = path.extname(filename).substr(1).toLowerCase(); + +if ('json' !== extname && 'bin' !== extname) { + console.error("The file extension must end in .json or .bin (raw DNS packet)"); + process.exit(3); + return; +} + +var hexdump = require('hexdump.js').hexdump; + +function testJsonAsync(nb) { + var packet = dnsjs.write(JSON.parse(nb.toString('ascii'))); + var str = hexdump(packet); + console.log(str); + var json = dnsjs.parse(packet); + if (json.error) { + console.error(json); + process.exit(37); + return; + } + + console.log("[OK] JSON -> binary -> JSON"); +} + +function testBinAsync(nb) { + var bin = nb.buffer.slice(nb.byteOffset, nb.byteOffset + nb.byteLength); + var json = dnsjs.parse(bin); + if (json.error) { + console.error(json); + process.exit(38); + return; + } + var bin = dnsjs.write(json); + var json2 = dnsjs.parse(bin); + if (json2.error) { + console.error(json2); + process.exit(37); + return; + } + + var assert = require('assert'); + json = JSON.parse(JSON.stringify()); + assert.deepEqual(json, json2); + + console.log("[OK] binary -> JSON -> binary -> JSON"); + console.log("(compression pointer support needs to be improved in order to support direct bin -> JSON -> bin testing)"); +} + +if ('json' === extname) { + return fs.readFileAsync(filename, null).then(testJsonAsync); +} + +if ('bin' === extname) { + return fs.readFileAsync(filename, null).then(testBinAsync); +} From 49b588c7a6985bda494691bf2d72a82f545b5cf3 Mon Sep 17 00:00:00 2001 From: AJ ONeal Date: Wed, 27 Sep 2017 14:40:51 -0600 Subject: [PATCH 34/41] pass json -> binary -> json test --- bin/dns-test.js | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/bin/dns-test.js b/bin/dns-test.js index 6fc2aef..f10d8d7 100644 --- a/bin/dns-test.js +++ b/bin/dns-test.js @@ -61,8 +61,8 @@ function testBinAsync(nb) { process.exit(38); return; } - var bin = dnsjs.write(json); - var json2 = dnsjs.parse(bin); + var bin2 = dnsjs.write(json); + var json2 = dnsjs.parse(bin2); if (json2.error) { console.error(json2); process.exit(37); @@ -70,7 +70,20 @@ function testBinAsync(nb) { } var assert = require('assert'); - json = JSON.parse(JSON.stringify()); + // EXPLANATION: + // The strategy used for compression pointers has not yet been proven + // as deterministic... and we don't implement them anyway, so this may not be the same + json = JSON.parse(JSON.stringify(json) + .replace(/,"labels":.*?\]/, '') + .replace(/,"cpcount":\d+/, '') + ); + json2 = JSON.parse(JSON.stringify(json2) + .replace(/,"labels":.*?\]/, '') + .replace(/,"cpcount":\d+/, '') + ); + //json2 = JSON.parse(JSON.stringify(json2)); + //console.log(json); + //console.log(json2); assert.deepEqual(json, json2); console.log("[OK] binary -> JSON -> binary -> JSON"); From 4ffce1d4051bfc33ddbc759fe32f811daecf974c Mon Sep 17 00:00:00 2001 From: AJ ONeal Date: Wed, 27 Sep 2017 17:29:27 -0600 Subject: [PATCH 35/41] make bins executable --- bin/dns-pack.js | 1 + bin/dns-parse.js | 1 + bin/dns-test.js | 35 +++++++++++++++++++++++++---------- bin/mdns-capture.js | 10 +++++++--- package.json | 8 +++++++- 5 files changed, 41 insertions(+), 14 deletions(-) mode change 100644 => 100755 bin/dns-pack.js mode change 100644 => 100755 bin/dns-parse.js mode change 100644 => 100755 bin/dns-test.js mode change 100644 => 100755 bin/mdns-capture.js diff --git a/bin/dns-pack.js b/bin/dns-pack.js old mode 100644 new mode 100755 index ddb6973..4bfb6c2 --- a/bin/dns-pack.js +++ b/bin/dns-pack.js @@ -1,3 +1,4 @@ +#!/usr/bin/env node 'use strict'; // EXAMPLE: diff --git a/bin/dns-parse.js b/bin/dns-parse.js old mode 100644 new mode 100755 index b5d6023..221f350 --- a/bin/dns-parse.js +++ b/bin/dns-parse.js @@ -1,3 +1,4 @@ +#!/usr/bin/env node 'use strict'; // EXAMPLE: diff --git a/bin/dns-test.js b/bin/dns-test.js old mode 100644 new mode 100755 index f10d8d7..4169245 --- a/bin/dns-test.js +++ b/bin/dns-test.js @@ -1,3 +1,4 @@ +#!/usr/bin/env node 'use strict'; // EXAMPLE: @@ -12,20 +13,12 @@ if (!filename || /(-h)|(--help)/.test(process.argv.join(' '))) { console.error(""); console.error("Accepts a DNS packet (binary or json), converts it, and then converts it back to verify the function of the parser and packer"); console.error(""); - console.error("Usage: node bin/dns-test.js "); - console.error("Example: node bin/dns-test.js ./samples/services-0.mdns.json"); + console.error("Usage: node bin/dns-test.js "); + console.error("Example: node bin/dns-test.js ./samples/services-0.mdns.json ./samples/services-0.mdns.bin"); process.exit(1); return; } -if (!outname) { - console.warn(''); - console.warn( - "Usage: node bin/dns-pack.js '" + filename + "' './" + path.basename(filename).replace(path.extname(filename), '') + ".bin'" - ); - console.warn(''); -} - var PromiseA = require('bluebird'); var fs = PromiseA.promisifyAll(require('fs')); var dnsjs = require('../').DNSPacket; @@ -51,6 +44,17 @@ function testJsonAsync(nb) { } console.log("[OK] JSON -> binary -> JSON"); + + if (!outname) { + console.warn(''); + console.warn( + "Usage: node bin/dns-test.js '" + filename + "' './" + path.basename(filename).replace(path.extname(filename), '.bin') + "'" + ); + console.warn(''); + return; + } + + fs.writeFileSync(path.basename(filename).replace(path.extname(filename), '.bin'), packet, null); } function testBinAsync(nb) { @@ -88,6 +92,17 @@ function testBinAsync(nb) { console.log("[OK] binary -> JSON -> binary -> JSON"); console.log("(compression pointer support needs to be improved in order to support direct bin -> JSON -> bin testing)"); + + if (!outname) { + console.warn(''); + console.warn( + "Usage: node bin/dns-test.js '" + filename + "' './" + path.basename(filename).replace(path.extname(filename), '.json') + "'" + ); + console.warn(''); + return; + } + + fs.writeFileSync(path.basename(filename).replace(path.extname(filename), '.json'), JSON.stringify(json, null, 2), null); } if ('json' === extname) { diff --git a/bin/mdns-capture.js b/bin/mdns-capture.js old mode 100644 new mode 100755 index beae2a4..c126973 --- a/bin/mdns-capture.js +++ b/bin/mdns-capture.js @@ -1,11 +1,13 @@ +#!/usr/bin/env node 'use strict'; // pass a terminal arg var type = process.argv[2]; var count = parseInt(process.argv[3]) || 0; if (!type) { - console.error("Usage: node aj-listener.js [count]"); - console.error("Example: node aj-listener.js _service 0"); + console.error("Usage: mdns-capture.js [start-number]"); + console.error("Example: mdns-capture.js _service 0"); + console.error("Output: _service-0.mdns.bin"); process.exit(1); } @@ -38,9 +40,11 @@ handlers.onListening = function () { /*jshint validthis:true*/ var server = this; console.log(server.address()); - + server.setBroadcast(true); server.addMembership('224.0.0.251'); + + console.log('CTRL+C to quit'); }; diff --git a/package.json b/package.json index 4000ccf..43582af 100644 --- a/package.json +++ b/package.json @@ -1,8 +1,14 @@ { "name": "dns-suite", - "version": "1.1.2", + "version": "1.2.0", "description": "testing dns", "main": "dns.js", + "bin": { + "dns-pack.js": "bin/dns-pack.js", + "dns-parse.js": "bin/dns-parse.js", + "dns-test.js": "bin/dns-test.js", + "mdns-capture.js": "bin/mdns-capture.js", + }, "scripts": { "test": "node test/parser.js && node test/packer.js" }, From 98187043eca463f1f360340d58b6252be34c0745 Mon Sep 17 00:00:00 2001 From: AJ ONeal Date: Thu, 28 Sep 2017 11:14:55 -0600 Subject: [PATCH 36/41] typo fix --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 43582af..061b93f 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,7 @@ "dns-pack.js": "bin/dns-pack.js", "dns-parse.js": "bin/dns-parse.js", "dns-test.js": "bin/dns-test.js", - "mdns-capture.js": "bin/mdns-capture.js", + "mdns-capture.js": "bin/mdns-capture.js" }, "scripts": { "test": "node test/parser.js && node test/packer.js" From a538fa4f58bc7b78e30cb5fb39553278f259e500 Mon Sep 17 00:00:00 2001 From: AJ ONeal Date: Thu, 28 Sep 2017 13:13:18 -0600 Subject: [PATCH 37/41] bugfix: add null terminators for packing SOA records --- bin/dns-test.js | 30 +++++++++++++++++++++--------- dns.unpack-labels.js | 4 ++++ packer/type.soa.js | 30 +++++++++++++++++++++--------- parser/type.soa.js | 23 ++++++++++++++--------- 4 files changed, 60 insertions(+), 27 deletions(-) diff --git a/bin/dns-test.js b/bin/dns-test.js index 4169245..6a7ac09 100755 --- a/bin/dns-test.js +++ b/bin/dns-test.js @@ -35,7 +35,7 @@ var hexdump = require('hexdump.js').hexdump; function testJsonAsync(nb) { var packet = dnsjs.write(JSON.parse(nb.toString('ascii'))); var str = hexdump(packet); - console.log(str); + console.info(str); var json = dnsjs.parse(packet); if (json.error) { console.error(json); @@ -43,7 +43,7 @@ function testJsonAsync(nb) { return; } - console.log("[OK] JSON -> binary -> JSON"); + console.info("[OK] JSON -> binary -> JSON"); if (!outname) { console.warn(''); @@ -54,7 +54,7 @@ function testJsonAsync(nb) { return; } - fs.writeFileSync(path.basename(filename).replace(path.extname(filename), '.bin'), packet, null); + fs.writeFileSync(outname, packet, null); } function testBinAsync(nb) { @@ -66,6 +66,8 @@ function testBinAsync(nb) { return; } var bin2 = dnsjs.write(json); + //var debugname = outname || path.basename(filename); + //fs.writeFileSync(debugname.replace(path.extname(debugname), '.bin'), bin2, null); var json2 = dnsjs.parse(bin2); if (json2.error) { console.error(json2); @@ -86,12 +88,22 @@ function testBinAsync(nb) { .replace(/,"cpcount":\d+/, '') ); //json2 = JSON.parse(JSON.stringify(json2)); - //console.log(json); - //console.log(json2); - assert.deepEqual(json, json2); + try { + assert.deepEqual(json, json2); + } catch(e) { + console.error(''); + console.error('Original'); + console.error(JSON.stringify(json, null, 2)); + console.error(''); + console.error('Converted'); + console.error(JSON.stringify(json2, null, 2)); + console.error(''); + process.exit(422); + return; + } - console.log("[OK] binary -> JSON -> binary -> JSON"); - console.log("(compression pointer support needs to be improved in order to support direct bin -> JSON -> bin testing)"); + console.info("[OK] binary -> JSON -> binary -> JSON"); + console.warn("(compression pointer support needs to be improved in order to support direct bin -> JSON -> bin testing)"); if (!outname) { console.warn(''); @@ -102,7 +114,7 @@ function testBinAsync(nb) { return; } - fs.writeFileSync(path.basename(filename).replace(path.extname(filename), '.json'), JSON.stringify(json, null, 2), null); + fs.writeFileSync(outname, JSON.stringify(json, null, 2), null); } if ('json' === extname) { diff --git a/dns.unpack-labels.js b/dns.unpack-labels.js index 0956fc0..9a82d43 100644 --- a/dns.unpack-labels.js +++ b/dns.unpack-labels.js @@ -46,6 +46,10 @@ exports.DNS_UNPACK_LABELS = function (ui8, ptr, q) { //str.length = 0; // fast empty array if (ui8.byteLength - total < len) { + //console.error('-1', ui8[total - 1]); + //console.error(' 0', ui8[total]); + //console.error(' 1', ui8[total + 1]); + //console.error(' 1', ui8[total + 2]); throw new Error( "Expected a string of length " + len + " but packet itself has " + (ui8.byteLength - total) + " bytes remaining" diff --git a/packer/type.soa.js b/packer/type.soa.js index d79a9f5..b33441a 100644 --- a/packer/type.soa.js +++ b/packer/type.soa.js @@ -1,6 +1,8 @@ (function (exports) { 'use strict'; +// http://www.zytrax.com/books/dns/ch8/soa.html + // Value Meaning/Use // Primary NS Variable length. The name of the Primary Master for the domain. May be a label, pointer, or any combination // Admin MB Variable length. The administrator's mailbox. May be a label, pointer, or any combination @@ -10,8 +12,6 @@ // Expiration Limit Unsigned 32-bit integer // Minimum TTL Unsigned 32-bit integer - - exports.DNS_PACKER_TYPE_SOA = function (ab, dv, total, record) { if(!record.name_server){ throw new Error("no name server for SOA record"); @@ -23,16 +23,16 @@ exports.DNS_PACKER_TYPE_SOA = function (ab, dv, total, record) { throw new Error("no serial number for SOA record"); } if(!record.ref){ - throw new Error("no serial number for SOA record"); + throw new Error("no refresh for SOA record"); } if(!record.ret){ - throw new Error("no serial number for SOA record"); + throw new Error("no update retry for SOA record"); } if(!record.ex){ - throw new Error("no serial number for SOA record"); + throw new Error("no expiry for SOA record"); } if(!record.nx){ - throw new Error("no serial number for SOA record"); + throw new Error("no nxdomain for SOA record"); } var soaLen = 20; // take into account sn, ref, ret, ex, and nx @@ -40,9 +40,10 @@ exports.DNS_PACKER_TYPE_SOA = function (ab, dv, total, record) { var rdLenIndex = total; total += 2; // Save space for RDLENGTH + console.log('record.name_server', 1 + record.name_server.length, record.name_server); // pack name_server which is a sequence of labels - record.name_server.split('.').forEach(function(label){ - soaLen += 1 + label.length; + record.name_server.split('.').forEach(function (label) { + soaLen += (1 + label.length); dv.setUint8(total, label.length, false); total += 1; @@ -52,9 +53,14 @@ exports.DNS_PACKER_TYPE_SOA = function (ab, dv, total, record) { total += 1; }); }); + // must be terminated by null when not using write null + dv.setUint8(total, 0, false); + total += 1; + soaLen += 1; + console.log('record.email_addr', 1 + record.email_addr.length, record.email_addr); // pack email address which is a sequence of labels - record.email_addr.split('.').forEach(function (label){ + record.email_addr.split('.').forEach(function (label) { soaLen += 1 + label.length; dv.setUint8(total, label.length, false); @@ -65,6 +71,10 @@ exports.DNS_PACKER_TYPE_SOA = function (ab, dv, total, record) { total += 1; }); }); + // must be terminated by null when not using write null + dv.setUint8(total, 0, false); + total += 1; + soaLen += 1; // pack all 32-bit values dv.setUint32(total, parseInt(record.sn, 10), false); @@ -79,6 +89,8 @@ exports.DNS_PACKER_TYPE_SOA = function (ab, dv, total, record) { total+=4; // RDLENGTH + console.log('rdAt', rdLenIndex); + console.log('soaLen (lables + 2 + 20)', soaLen); dv.setUint16(rdLenIndex, soaLen, false); return total; diff --git a/parser/type.soa.js b/parser/type.soa.js index 2ca64ff..eda05b8 100644 --- a/parser/type.soa.js +++ b/parser/type.soa.js @@ -18,27 +18,31 @@ exports.DNS_PARSER_TYPE_SOA = function (ab, packet, record) { var dv = new DataView(rdataAb); // we need this information for this parser - var cpcount = unpackLabels(new Uint8Array(ab), record.rdstart, { byteLength: 0, cpcount: 0, labels: [], name: '' }).cpcount; - var offset = unpackLabels(new Uint8Array(ab), record.rdstart, { byteLength: 0, cpcount: 0, labels: [], name: '' }).byteLength; - var labels = unpackLabels(new Uint8Array(ab), record.rdstart, { byteLength: 0, cpcount: 0, labels: [], name: '' }).labels; + var labelInfo = unpackLabels(new Uint8Array(ab), record.rdstart, { byteLength: 0, cpcount: 0, labels: [], name: '' }); + var cpcount = labelInfo.cpcount; + var offset = labelInfo.byteLength; + var labels = labelInfo.labels; // Primary NS - record.name_server = unpackLabels(new Uint8Array(ab), record.rdstart, { byteLength: 0, cpcount: 0, labels: [], name: '' }).name; + record.name_server = labelInfo.name; + // TODO delete this commented out code after some testing + // (pretty sure it was unnecessary and it seemed to work on code with compression pointers just fine) + /* // if there exists compression pointers in the rdata - if (cpcount > 0){ + if (cpcount > 0) { // do something awesome with compression pointers to get the email address // I need the length of all the data before the email address starts. // if there are compression pointers then there will be a byte to indicate the length of each label, the label, // then there will be a compression pointer to grab the longest label. var start = 2; // start or email_addr. take into account compression pointer and address length - for(var i = 0; i < labels.length; i++){ + for (var i = 0; i < labels.length; i += 1) { // increase start by the label length. the +1 is to take into account the next label size byte start = start + labels[i].length + 1; // check for cpcount. 2 counts behind - if(parseInt(dv.getUint8(start - 2), 10) === 192){ + if (parseInt(dv.getUint8(start - 2), 10) === 192) { record.email_addr = unpackLabels(new Uint8Array(ab), record.rdstart + start ,{ byteLength: 0, cpcount: 0, labels: [], name: '' }).name; } } @@ -47,6 +51,9 @@ exports.DNS_PARSER_TYPE_SOA = function (ab, packet, record) { record.email_addr = unpackLabels(new Uint8Array(ab), record.rdstart + offset, { byteLength: 0, cpcount: 0, labels: [], name: '' }).name; } + */ + record.email_addr = unpackLabels(new Uint8Array(ab), record.rdstart + offset, { byteLength: 0, cpcount: 0, labels: [], name: '' }).name; + // Serial Number record.sn = dv.getUint32(dv.byteLength - 20, false); // Refresh Interval @@ -58,9 +65,7 @@ exports.DNS_PARSER_TYPE_SOA = function (ab, packet, record) { // Minimum TTL record.nx = dv.getUint32(dv.byteLength - 4, false); - return record; - }; }('undefined' !== typeof window ? window : exports)); From a287abb991e19cb2fb808407ea2e22a7fd3998de Mon Sep 17 00:00:00 2001 From: AJ ONeal Date: Thu, 28 Sep 2017 13:13:50 -0600 Subject: [PATCH 38/41] v1.2.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 061b93f..e2f2e64 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "dns-suite", - "version": "1.2.0", + "version": "1.2.1", "description": "testing dns", "main": "dns.js", "bin": { From d66624df8e16a497cef73deb095ca105119935a8 Mon Sep 17 00:00:00 2001 From: AJ ONeal Date: Thu, 28 Sep 2017 13:30:03 -0600 Subject: [PATCH 39/41] add new bins to README --- README.md | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index 3a6d494..b8ce807 100644 --- a/README.md +++ b/README.md @@ -92,27 +92,24 @@ Usage * CLI * API -**CLI** +### CLI Usage -You can work directly from `node_modules/dns-suite`: +When installed globally you can use these commands: -```bash -pushd node_modules/dns-suite/ +``` +dns-parse.js [out.json] # parses a saved DNS packet to JSON +dns-pack.js [out.bin] # packs a JSON DNS packet to binary +dns-test.js # convert a packet back and forth to test reciprocity of the packer and parser +mdns-capture.js [startnum] # listen and save all mDNS packets, numbering by sequence of arrival ``` -Parsing a saved packet +You can also access them directly from `node_modules/dns-suite` in a project: ```bash -# example -# node bin/dns-parse.js -node bin/dns-parse.js samples/a-0.mdns.bin +node node_modules/dns-suite/bin/dns-parse.js node_modules/dns-suite/samples/a-0.mdns.bin ``` -You can also parse a saved packet from the `native-dns-packet` directory. -these test packets have the binary for each record type and what it's parsed output -should be. - -**Library** +### Library API * `DNSPacket.parse(nodeOrArrayBuffer)` returns json (as shown above) * `DNSPacket.pack(packet)` returns ArrayBuffer (browser and node) From 777bbd679fdc7c505d20a9f6bc23502a007813a2 Mon Sep 17 00:00:00 2001 From: AJ ONeal Date: Thu, 28 Sep 2017 13:30:05 -0600 Subject: [PATCH 40/41] v1.2.2 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index e2f2e64..b484f45 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "dns-suite", - "version": "1.2.1", + "version": "1.2.2", "description": "testing dns", "main": "dns.js", "bin": { From 93cdeaa71b434a8b4fe30690ac9813e0b1aa5022 Mon Sep 17 00:00:00 2001 From: AJ ONeal Date: Fri, 29 Sep 2017 17:57:34 -0600 Subject: [PATCH 41/41] Update package.json --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index b484f45..b9f7d9f 100644 --- a/package.json +++ b/package.json @@ -18,7 +18,7 @@ }, "author": "", "license": "(MIT or Apache2)", - "developmentDependencies": { + "devDependencies": { "bluebird": "^3.5.0" } }