From 9f48a7fcfb9a2ec467b4b10e5609ecaefa5a0dcd Mon Sep 17 00:00:00 2001 From: kmpm Date: Thu, 25 Sep 2014 17:59:06 +0200 Subject: [PATCH 1/6] Enable parsing of answers without question Implements first part of issue #1. Tests and closes #14 --- packet.js | 5 ++ test/fixtures/mdns.readynas.bin | Bin 0 -> 360 bytes test/fixtures/mdns.readynas.js | 83 ++++++++++++++++++++++++++++++++ 3 files changed, 88 insertions(+) create mode 100644 test/fixtures/mdns.readynas.bin create mode 100644 test/fixtures/mdns.readynas.js diff --git a/packet.js b/packet.js index 60dc8a5..dfc2d88 100644 --- a/packet.js +++ b/packet.js @@ -492,6 +492,11 @@ function parseHeader(msg, packet, counts) { } function parseQuestion(msg, packet) { + if (packet.header.opcode === 0 && // Standard query + packet.header.qr === 1 && // Response + packet.question.length === 0) { // Empty question can occur in mDNS + return PARSE_RESOURCE_RECORD; + } var val = {}; val.name = nameUnpack(msg); val.type = msg.readUInt16BE(); diff --git a/test/fixtures/mdns.readynas.bin b/test/fixtures/mdns.readynas.bin new file mode 100644 index 0000000000000000000000000000000000000000..1c848dfaf03a6946533ff0067971841b7d934d36 GIT binary patch literal 360 zcmZ9IK@Ng25JkrXL?S|>OP8*>2e+71T7d|(=?oh89*mM7&HMtqLC#^h zQY7OaU2P~qJyJ Date: Thu, 25 Sep 2014 22:06:48 +0200 Subject: [PATCH 2/6] Support packet with multiple question Part 2 of issue #1. Test packet generated by 2 chromecast devices Still some issues when writing so roundtrip does not work. --- packet.js | 16 +++++++------ test/fixtures/chromecast.bin | Bin 0 -> 259 bytes test/fixtures/chromecast.js | 45 +++++++++++++++++++++++++++++++++++ 3 files changed, 54 insertions(+), 7 deletions(-) create mode 100644 test/fixtures/chromecast.bin create mode 100644 test/fixtures/chromecast.js diff --git a/packet.js b/packet.js index dfc2d88..abe86cb 100644 --- a/packet.js +++ b/packet.js @@ -497,13 +497,15 @@ function parseQuestion(msg, packet) { packet.question.length === 0) { // Empty question can occur in mDNS return PARSE_RESOURCE_RECORD; } - var val = {}; - val.name = nameUnpack(msg); - val.type = msg.readUInt16BE(); - val.class = msg.readUInt16BE(); - packet.question[0] = val; - assert(packet.question.length === 1); - // TODO handle qdcount > 0 in practice no one sends this + var qnum = packet.question.length; + while (qnum > 0) { + var val = {}; + val.name = nameUnpack(msg); + val.type = msg.readUInt16BE(); + val.class = msg.readUInt16BE(); + packet.question[packet.question.length - qnum] = val; + qnum -= 1; + } return PARSE_RESOURCE_RECORD; } diff --git a/test/fixtures/chromecast.bin b/test/fixtures/chromecast.bin new file mode 100644 index 0000000000000000000000000000000000000000..afefc39caf3c6a05f98a0d1e4945a32db9856356 GIT binary patch literal 259 zcmZQz00K@1CJ@CPpPrweo|BrKSX{yqUy@wFnvprN%4GPn!{ gE5L53EJzp7Sv(AkKu@h@U^<`y=dENA$F7M700LxF&Hw-a literal 0 HcmV?d00001 diff --git a/test/fixtures/chromecast.js b/test/fixtures/chromecast.js new file mode 100644 index 0000000..267b220 --- /dev/null +++ b/test/fixtures/chromecast.js @@ -0,0 +1,45 @@ +{ header: + { id: 0, + qr: 0, + opcode: 0, + aa: 0, + tc: 0, + rd: 0, + ra: 0, + res1: 0, + res2: 0, + res3: 0, + rcode: 0 }, + question: + [ { name: '_googlecast._tcp.local', type: 12, class: 32769 }, + { name: 'TV i Vardagsrummet._googlecast._tcp.local', + type: 33, + class: 32769 }, + { name: 'TV i Vardagsrummet._googlecast._tcp.local', + type: 16, + class: 32769 }, + { name: 'SkC$rm i GC$strummet._googlecast._tcp.local', + type: 33, + class: 32769 }, + { name: 'SkC$rm i GC$strummet._googlecast._tcp.local', + type: 16, + class: 32769 }, + { name: 'TV i Vardagsrummet.local', type: 1, class: 32769 }, + { name: 'TV i Vardagsrummet.local', type: 28, class: 32769 }, + { name: 'SkC$rm i GC$strummet.local', type: 1, class: 32769 }, + { name: 'SkC$rm i GC$strummet.local', type: 28, class: 32769 } ], + answer: + [ { name: '_googlecast._tcp.local', + type: 12, + class: 1, + ttl: 2477, + data: 'TV i Vardagsrummet._googlecast._tcp.local' }, + { name: '_googlecast._tcp.local', + type: 12, + class: 1, + ttl: 2473, + data: 'SkC$rm i GC$strummet._googlecast._tcp.local' } ], + authority: [], + additional: [], + edns_options: [], + payload: undefined } \ No newline at end of file From 296bfe5337b57e93a605838a4da48924e8d46e4b Mon Sep 17 00:00:00 2001 From: Greg Slepak Date: Sun, 5 Oct 2014 16:40:19 -0700 Subject: [PATCH 3/6] 0.1.1 - fixes for npm tags... --- README.md | 4 ++++ package.json | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 3146618..429254a 100644 --- a/README.md +++ b/README.md @@ -31,6 +31,10 @@ var Packet = function () { ## History +###### 0.1.1 - October 5, 2014 + +- Fixing NPM tagging issue... + ###### 0.1.0 - October 2, 2014 - Added TLSA support diff --git a/package.json b/package.json index a39c164..04b0269 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "native-dns-packet", - "version": "0.1.0", + "version": "0.1.1", "authors": [ "Timothy J Fontaine (http://atxconsulting.com)", "Greg Slepak (https://twitter.com/taoeffect)", From c019155b698b95d0588e1590fcf87742900ce23e Mon Sep 17 00:00:00 2001 From: kmpm Date: Thu, 25 Sep 2014 17:59:06 +0200 Subject: [PATCH 4/6] Enable parsing of answers without question Implements first part of issue #1. Tests and closes #14 --- packet.js | 5 ++ test/fixtures/mdns.readynas.bin | Bin 0 -> 360 bytes test/fixtures/mdns.readynas.js | 83 ++++++++++++++++++++++++++++++++ 3 files changed, 88 insertions(+) create mode 100644 test/fixtures/mdns.readynas.bin create mode 100644 test/fixtures/mdns.readynas.js diff --git a/packet.js b/packet.js index 56b17d9..2eae580 100644 --- a/packet.js +++ b/packet.js @@ -521,6 +521,11 @@ function parseHeader(msg, packet) { } function parseQuestion(msg, packet) { + if (packet.header.opcode === 0 && // Standard query + packet.header.qr === 1 && // Response + packet.question.length === 0) { // Empty question can occur in mDNS + return PARSE_RESOURCE_RECORD; + } var val = {}; val.name = nameUnpack(msg); val.type = msg.readUInt16BE(); diff --git a/test/fixtures/mdns.readynas.bin b/test/fixtures/mdns.readynas.bin new file mode 100644 index 0000000000000000000000000000000000000000..1c848dfaf03a6946533ff0067971841b7d934d36 GIT binary patch literal 360 zcmZ9IK@Ng25JkrXL?S|>OP8*>2e+71T7d|(=?oh89*mM7&HMtqLC#^h zQY7OaU2P~qJyJ Date: Thu, 25 Sep 2014 22:06:48 +0200 Subject: [PATCH 5/6] Support packet with multiple question Part 2 of issue #1. Test packet generated by 2 chromecast devices Still some issues when writing so roundtrip does not work. --- packet.js | 18 +++++++------- test/fixtures/chromecast.bin | Bin 0 -> 259 bytes test/fixtures/chromecast.js | 45 +++++++++++++++++++++++++++++++++++ 3 files changed, 55 insertions(+), 8 deletions(-) create mode 100644 test/fixtures/chromecast.bin create mode 100644 test/fixtures/chromecast.js diff --git a/packet.js b/packet.js index 2eae580..c5703d2 100644 --- a/packet.js +++ b/packet.js @@ -526,13 +526,15 @@ function parseQuestion(msg, packet) { packet.question.length === 0) { // Empty question can occur in mDNS return PARSE_RESOURCE_RECORD; } - var val = {}; - val.name = nameUnpack(msg); - val.type = msg.readUInt16BE(); - val.class = msg.readUInt16BE(); - packet.question[0] = val; - assert(packet.question.length === 1); - // TODO handle qdcount > 1 in practice no one sends this + var qnum = packet.question.length; + while (qnum > 0) { + var val = {}; + val.name = nameUnpack(msg); + val.type = msg.readUInt16BE(); + val.class = msg.readUInt16BE(); + packet.question[packet.question.length - qnum] = val; + qnum -= 1; + } return PARSE_RESOURCE_RECORD; } @@ -683,7 +685,7 @@ var PARSE_OPT = consts.NAME_TO_QTYPE.OPT, PARSE_SPF = consts.NAME_TO_QTYPE.SPF, PARSE_TLSA = consts.NAME_TO_QTYPE.TLSA; - + Packet.parse = function(msg) { var state, diff --git a/test/fixtures/chromecast.bin b/test/fixtures/chromecast.bin new file mode 100644 index 0000000000000000000000000000000000000000..afefc39caf3c6a05f98a0d1e4945a32db9856356 GIT binary patch literal 259 zcmZQz00K@1CJ@CPpPrweo|BrKSX{yqUy@wFnvprN%4GPn!{ gE5L53EJzp7Sv(AkKu@h@U^<`y=dENA$F7M700LxF&Hw-a literal 0 HcmV?d00001 diff --git a/test/fixtures/chromecast.js b/test/fixtures/chromecast.js new file mode 100644 index 0000000..267b220 --- /dev/null +++ b/test/fixtures/chromecast.js @@ -0,0 +1,45 @@ +{ header: + { id: 0, + qr: 0, + opcode: 0, + aa: 0, + tc: 0, + rd: 0, + ra: 0, + res1: 0, + res2: 0, + res3: 0, + rcode: 0 }, + question: + [ { name: '_googlecast._tcp.local', type: 12, class: 32769 }, + { name: 'TV i Vardagsrummet._googlecast._tcp.local', + type: 33, + class: 32769 }, + { name: 'TV i Vardagsrummet._googlecast._tcp.local', + type: 16, + class: 32769 }, + { name: 'SkC$rm i GC$strummet._googlecast._tcp.local', + type: 33, + class: 32769 }, + { name: 'SkC$rm i GC$strummet._googlecast._tcp.local', + type: 16, + class: 32769 }, + { name: 'TV i Vardagsrummet.local', type: 1, class: 32769 }, + { name: 'TV i Vardagsrummet.local', type: 28, class: 32769 }, + { name: 'SkC$rm i GC$strummet.local', type: 1, class: 32769 }, + { name: 'SkC$rm i GC$strummet.local', type: 28, class: 32769 } ], + answer: + [ { name: '_googlecast._tcp.local', + type: 12, + class: 1, + ttl: 2477, + data: 'TV i Vardagsrummet._googlecast._tcp.local' }, + { name: '_googlecast._tcp.local', + type: 12, + class: 1, + ttl: 2473, + data: 'SkC$rm i GC$strummet._googlecast._tcp.local' } ], + authority: [], + additional: [], + edns_options: [], + payload: undefined } \ No newline at end of file From f2b4448b54913798ba74142d54f6f765bf7f9289 Mon Sep 17 00:00:00 2001 From: Peter Magnusson Date: Mon, 6 Oct 2014 12:03:18 +0200 Subject: [PATCH 6/6] write multiple questions --- packet.js | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/packet.js b/packet.js index c5703d2..4eb8ba8 100644 --- a/packet.js +++ b/packet.js @@ -169,9 +169,8 @@ function writeHeader(buff, packet) { val += (packet.header.res3 << 4) & 0x10; val += packet.header.rcode & 0xF; buff.writeUInt16BE(val & 0xFFFF); - assert(packet.question.length == 1, 'DNS requires one question'); - // aren't used - buff.writeUInt16BE(1); + // question offset 4 + buff.writeUInt16BE(packet.question.length & 0xFFFF); // answer offset 6 buff.writeUInt16BE(packet.answer.length & 0xFFFF); // authority offset 8 @@ -233,7 +232,6 @@ function writeQuestion(buff, val, label_index) { namePack(val.name, buff, label_index); buff.writeUInt16BE(val.type & 0xFFFF); buff.writeUInt16BE(val.class & 0xFFFF); - return WRITE_RESOURCE_RECORD; } function writeResource(buff, val, label_index, rdata) { @@ -411,14 +409,21 @@ Packet.write = function(buff, packet) { switch (state) { case WRITE_HEADER: state = writeHeader(buff, packet); + count = 0; break; case WRITE_TRUNCATE: state = writeTruncate(buff, packet, section, last_resource); break; case WRITE_QUESTION: - state = writeQuestion(buff, packet.question[0], label_index); - section = 'answer'; - count = 0; + if(count === packet.question.length) { + state = WRITE_RESOURCE_RECORD; + section = 'answer'; + count = 0; + } + else { + writeQuestion(buff, packet.question[count], label_index); + count += 1 + } break; case WRITE_RESOURCE_RECORD: last_resource = buff.tell();