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)", diff --git a/packet.js b/packet.js index 56b17d9..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(); @@ -521,13 +526,20 @@ function parseHeader(msg, packet) { } function parseQuestion(msg, packet) { - 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 + 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 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; } @@ -678,7 +690,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 0000000..afefc39 Binary files /dev/null and b/test/fixtures/chromecast.bin differ 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 diff --git a/test/fixtures/mdns.readynas.bin b/test/fixtures/mdns.readynas.bin new file mode 100644 index 0000000..1c848df Binary files /dev/null and b/test/fixtures/mdns.readynas.bin differ diff --git a/test/fixtures/mdns.readynas.js b/test/fixtures/mdns.readynas.js new file mode 100644 index 0000000..ceed7ee --- /dev/null +++ b/test/fixtures/mdns.readynas.js @@ -0,0 +1,83 @@ +{ header: + { id: 0, + qr: 1, + opcode: 0, + aa: 1, + tc: 0, + rd: 0, + ra: 0, + res1: 0, + res2: 0, + res3: 0, + rcode: 0 }, + question: [], + answer: + [ { name: '_services._dns-sd._udp.local', + type: 12, + class: 1, + ttl: 3599, + data: '_transmissionserver._tcp.local' }, + { name: '_services._dns-sd._udp.local', + type: 12, + class: 1, + ttl: 3599, + data: '_ssh._tcp.local' }, + { name: '_services._dns-sd._udp.local', + type: 12, + class: 1, + ttl: 3599, + data: '_https._tcp.local' }, + { name: '_services._dns-sd._udp.local', + type: 12, + class: 1, + ttl: 3599, + data: '_workstation._tcp.local' }, + { name: '_services._dns-sd._udp.local', + type: 12, + class: 1, + ttl: 3599, + data: '_afpovertcp._tcp.local' }, + { name: '_services._dns-sd._udp.local', + type: 12, + class: 1, + ttl: 3599, + data: '_readynas._tcp.local' }, + { name: '_services._dns-sd._udp.local', + type: 12, + class: 1, + ttl: 3599, + data: '_ftp._tcp.local' }, + { name: '_services._dns-sd._udp.local', + type: 12, + class: 1, + ttl: 3599, + data: '_pdl-datastream._tcp.local' }, + { name: '_services._dns-sd._udp.local', + type: 12, + class: 1, + ttl: 3599, + data: '_sftp-ssh._tcp.local' }, + { name: '_services._dns-sd._udp.local', + type: 12, + class: 1, + ttl: 3599, + data: '_googlecast._tcp.local' }, + { name: '_services._dns-sd._udp.local', + type: 12, + class: 1, + ttl: 3599, + data: '_smb._tcp.local' }, + { name: '_services._dns-sd._udp.local', + type: 12, + class: 1, + ttl: 3599, + data: '_udisks-ssh._tcp.local' }, + { name: '_services._dns-sd._udp.local', + type: 12, + class: 1, + ttl: 3599, + data: '_http._tcp.local' } ], + authority: [], + additional: [], + edns_options: [], + payload: undefined } \ No newline at end of file