From 442c5c8a205fbc16c34763e28f9a193d07a5914e Mon Sep 17 00:00:00 2001 From: AJ ONeal Date: Fri, 17 Feb 2017 20:27:13 -0700 Subject: [PATCH] update docs --- ORIGINAL_PROBLEM.md | 262 +++++++++++++++++++++++++++++++++++++++++++ README.md | 264 -------------------------------------------- 2 files changed, 262 insertions(+), 264 deletions(-) create mode 100644 ORIGINAL_PROBLEM.md diff --git a/ORIGINAL_PROBLEM.md b/ORIGINAL_PROBLEM.md new file mode 100644 index 0000000..8acdac7 --- /dev/null +++ b/ORIGINAL_PROBLEM.md @@ -0,0 +1,262 @@ +mDNS Documentation +==== + +This document is currently used and update for testing purposes of DNS packets with Daplie applications. Please make note of any errata, as the organization of this document is based on the step by step process of debugging current issues regarding DNS, and not necessarily a demonstration on how to fix those issues. This document is for learning purposes and meant to assist future developers avoid similar bugs. + + +## Objective + +Create a robust DNS library that checks all possible combinations of DNS flags and messages in order to debug current DNS state for Daplie system and potentially develope DNS library with built in linting for use of Daplie, inc and community. + + +### How to duplicate DNS crash: + +``` +>> cd ~/dns_test +>> node listen.jss +``` +Then in another terminal enter: + +``` +>> dig @224.0.0.251 -p 5353 -t PTR _cloud._tcp.local +``` + +The listener then crashes with an output of: + +``` +START DNS PACKET +/home/daplie/dns_test/node_modules/dns-js/lib/bufferconsumer.js:52 + throw new Error('Buffer overflow') + ^ + +Error: Buffer overflow + at BufferConsumer.slice (/home/daplie/dns_test/node_modules/dns-js/lib/bufferconsumer.js:52:13) + s at Function.DNSRecord.parse (/home/daplie/dns_test/node_modules/dns-js/lib/dnsrecord.js:237:46) + at /home/daplie/dns_test/node_modules/dns-js/lib/dnspacket.js:164:30 + at Array.forEach (native) + at Function.DNSPacket.parse (/home/daplie/dns_test/node_modules/dns-js/lib/dnspacket.js:159:17) + at /home/daplie/dns_test/cloud-respond.js:86:31 + at Array.forEach (native) + at /home/daplie/dns_test/cloud-respond.js:11:21 + at Array.forEach (native) + at Object.module.exports.respond (/home/daplie/dns_test/cloud-respond.js:10:11) + +``` +After commenting out lines 45-53 in dns_test/node_modules/dns-js/lib/bufferconsumer.js +and rerunning the previous commands, the result is a new error: + +``` +START DNS PACKET +buffer.js:829 + throw new RangeError('Index out of range'); + ^ + +RangeError: Index out of range + at checkOffset (buffer.js:829:11) + at Buffer.readUInt8 (buffer.js:867:5) + at BufferConsumer.byte (/home/daplie/dns_test/node_modules/dns-js/lib/bufferconsumer.js:67:22) + at BufferConsumer.name (/home/daplie/dns_test/node_modules/dns-js/lib/bufferconsumer.js:120:14) + at Function.DNSRecord.parse (/home/daplie/dns_test/node_modules/dns-js/lib/dnsrecord.js:187:14) + at /home/daplie/dns_test/node_modules/dns-js/lib/dnspacket.js:164:30 + at Array.forEach (native) + at Function.DNSPacket.parse (/home/daplie/dns_test/node_modules/dns-js/lib/dnspacket.js:159:17) + at /home/daplie/dns_test/cloud-respond.js:86:31 + at Array.forEach (native) + +``` +which is located in the node.js buffer module. The API is [here](https://nodejs.org/api/buffer.html). + +However, the error we are working with will most likely be dealt with by parsing through the binary +and putting it in a format that is acceptable to a custom buffer, since the current buffer.js does doesn't seem to do the trick. + +Using + +```javascript +function pad(str, len, ch) { + + while (str.length < len) { + str = ch + str; + } + + return str; +} +``` +the binary output comes out as: + +``` +11100001 +10001000 +00000001 +00100000 +00000000 +00000001 +00000000 +00000000 +00000000 +00000000 +00000000 +00000001 +00000110 +01011111 +01100011 +01101100 +01101111 +01110101 +01100100 +00000100 +01011111 +01110100 +01100011 +01110000 +00000101 +01101100 +01101111 +01100011 +01100001 +01101100 +00000000 +00000000 +00001100 +00000000 +00000001 +00000000 +00000000 +00101001 +00010000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +``` + +In order to figure out where the dnspacket code is going wrong, +We will have to write our own test code to see if the dns code +is doing what it's supposed to be doing. + +Looking at the code below: + +```javascript +// parses through the flags +// val can be 1 or 0 +// (val & 0x8000) >> 15 does the following +// val = 0000 0000 0000 0001 +// & 1001 0000 0000 0000 +// _______________________ +// 0000 0000 0000 0000 +// same if val were 0 +// but if val were 0x8000 +// then +// (val & 0x8000) >> 15 does the following +// val = 1001 0000 0000 0001 +// & 1001 0000 0000 0000 +// _______________________ +// 1001 0000 0000 0000 +// >>15= 0000 0000 0000 0001 + +function parseFlags(val, packet) { + packet.header.qr = (val & 0x8000) >> 15; + packet.header.opcode = (val & 0x7800) >> 11; + packet.header.aa = (val & 0x400) >> 10; + packet.header.tc = (val & 0x200) >> 9; + packet.header.rd = (val & 0x100) >> 8; + packet.header.ra = (val & 0x80) >> 7; + packet.header.res1 = (val & 0x40) >> 6; + packet.header.res2 = (val & 0x20) >> 5; + packet.header.res3 = (val & 0x10) >> 4; + packet.header.rcode = (val & 0xF); +} +``` + +One effective way to check is to create a dns packet, pass it to +a custom packer and parser function and compare the input and output: + +```javascript +'use strict'; + +// order one http://www.binarytides.com/dns-query-code-in-c-with-linux-sockets/ +// order two http://www.zytrax.com/books/dns/ch15/ + +function parse(i) { + var header = { + // first byte appears to be reverse + qr: (i & 0x8000) >> 15 + , opcode: (i & 0x7800) >> 11 + , aa: (i & 0x400) >> 10 + , tc: (i & 0x200) >> 9 + , rd: (i & 0x100) >> 8 + + // second byte appears to be second byte, but also in reverse + , ra: (i & 0x80) >> 7 + , res1: (i & 0x40) >> 6 // z + , res2: (i & 0x20) >> 5 // ad + , res3: (i & 0x10) >> 4 // cd + , rcode: (i & 0x1F) + }; + + return header; +} + +function pack(header) { + var val = 0; + + val += (header.qr << 15) & 0x8000; + val += (header.opcode << 11) & 0x7800; + val += (header.aa << 10) & 0x400; + val += (header.tc << 9) & 0x200; + val += (header.rd << 8) & 0x100; + val += (header.ra << 7) & 0x80; + val += (header.res1 << 6) & 0x40; + val += (header.res2 << 5) & 0x20; + val += (header.res3 << 4) & 0x10; + val += header.rcode & 0x1F; + + return val; +} + +var start = { + qr: 1 +, opcode: 12 +, aa: 0 +, tc: 0 +, rd: 1 +, ra: 0 +, res1: 0 +, res2: 0 +, res3: 0 +, rcode: 0 +}; + +var i = pack(start); + +var obj = parse(i); + +console.log(i); +console.log(start); +console.log(obj); +// does a recursive check to see if start and obj are equal +require('assert').deepEqual(start, obj); + +``` + + + + +How to print out hex values of the DNS message in node.js? + +```javascript +socket.on('message', function (message, rinfo) { + console.log('Received %d bytes from %s:%d\n', + message.length, rinfo.address, rinfo.port); + //console.log(msg.toString('utf8')); + + console.log(message.toString('hex')); +``` + + + +DNS sec: security +puts a signature on a DNS packet and imprints a signature so that the sender of +the packet is confirmed diff --git a/README.md b/README.md index 9474dde..2e42063 100644 --- a/README.md +++ b/README.md @@ -219,267 +219,3 @@ At the very least someone can follow a few links you followed and your thought p    ├── www.google.com.cname.bin    └── www.google.com.cname.js ``` - - -mDNS Documentation -==== - -This document is currently used and update for testing purposes of DNS packets with Daplie applications. Please make note of any errata, as the organization of this document is based on the step by step process of debugging current issues regarding DNS, and not necessarily a demonstration on how to fix those issues. This document is for learning purposes and meant to assist future developers avoid similar bugs. - - -## Objective - -Create a robust DNS library that checks all possible combinations of DNS flags and messages in order to debug current DNS state for Daplie system and potentially develope DNS library with built in linting for use of Daplie, inc and community. - - -### How to duplicate DNS crash: - -``` ->> cd ~/dns_test ->> node listen.jss -``` -Then in another terminal enter: - -``` ->> dig @224.0.0.251 -p 5353 -t PTR _cloud._tcp.local -``` - -The listener then crashes with an output of: - -``` -START DNS PACKET -/home/daplie/dns_test/node_modules/dns-js/lib/bufferconsumer.js:52 - throw new Error('Buffer overflow') - ^ - -Error: Buffer overflow - at BufferConsumer.slice (/home/daplie/dns_test/node_modules/dns-js/lib/bufferconsumer.js:52:13) - s at Function.DNSRecord.parse (/home/daplie/dns_test/node_modules/dns-js/lib/dnsrecord.js:237:46) - at /home/daplie/dns_test/node_modules/dns-js/lib/dnspacket.js:164:30 - at Array.forEach (native) - at Function.DNSPacket.parse (/home/daplie/dns_test/node_modules/dns-js/lib/dnspacket.js:159:17) - at /home/daplie/dns_test/cloud-respond.js:86:31 - at Array.forEach (native) - at /home/daplie/dns_test/cloud-respond.js:11:21 - at Array.forEach (native) - at Object.module.exports.respond (/home/daplie/dns_test/cloud-respond.js:10:11) - -``` -After commenting out lines 45-53 in dns_test/node_modules/dns-js/lib/bufferconsumer.js -and rerunning the previous commands, the result is a new error: - -``` -START DNS PACKET -buffer.js:829 - throw new RangeError('Index out of range'); - ^ - -RangeError: Index out of range - at checkOffset (buffer.js:829:11) - at Buffer.readUInt8 (buffer.js:867:5) - at BufferConsumer.byte (/home/daplie/dns_test/node_modules/dns-js/lib/bufferconsumer.js:67:22) - at BufferConsumer.name (/home/daplie/dns_test/node_modules/dns-js/lib/bufferconsumer.js:120:14) - at Function.DNSRecord.parse (/home/daplie/dns_test/node_modules/dns-js/lib/dnsrecord.js:187:14) - at /home/daplie/dns_test/node_modules/dns-js/lib/dnspacket.js:164:30 - at Array.forEach (native) - at Function.DNSPacket.parse (/home/daplie/dns_test/node_modules/dns-js/lib/dnspacket.js:159:17) - at /home/daplie/dns_test/cloud-respond.js:86:31 - at Array.forEach (native) - -``` -which is located in the node.js buffer module. The API is [here](https://nodejs.org/api/buffer.html). - -However, the error we are working with will most likely be dealt with by parsing through the binary -and putting it in a format that is acceptable to a custom buffer, since the current buffer.js does doesn't seem to do the trick. - -Using - -```javascript -function pad(str, len, ch) { - - while (str.length < len) { - str = ch + str; - } - - return str; -} -``` -the binary output comes out as: - -``` -11100001 -10001000 -00000001 -00100000 -00000000 -00000001 -00000000 -00000000 -00000000 -00000000 -00000000 -00000001 -00000110 -01011111 -01100011 -01101100 -01101111 -01110101 -01100100 -00000100 -01011111 -01110100 -01100011 -01110000 -00000101 -01101100 -01101111 -01100011 -01100001 -01101100 -00000000 -00000000 -00001100 -00000000 -00000001 -00000000 -00000000 -00101001 -00010000 -00000000 -00000000 -00000000 -00000000 -00000000 -00000000 -00000000 -``` - -In order to figure out where the dnspacket code is going wrong, -We will have to write our own test code to see if the dns code -is doing what it's supposed to be doing. - -Looking at the code below: - -```javascript -// parses through the flags -// val can be 1 or 0 -// (val & 0x8000) >> 15 does the following -// val = 0000 0000 0000 0001 -// & 1001 0000 0000 0000 -// _______________________ -// 0000 0000 0000 0000 -// same if val were 0 -// but if val were 0x8000 -// then -// (val & 0x8000) >> 15 does the following -// val = 1001 0000 0000 0001 -// & 1001 0000 0000 0000 -// _______________________ -// 1001 0000 0000 0000 -// >>15= 0000 0000 0000 0001 - -function parseFlags(val, packet) { - packet.header.qr = (val & 0x8000) >> 15; - packet.header.opcode = (val & 0x7800) >> 11; - packet.header.aa = (val & 0x400) >> 10; - packet.header.tc = (val & 0x200) >> 9; - packet.header.rd = (val & 0x100) >> 8; - packet.header.ra = (val & 0x80) >> 7; - packet.header.res1 = (val & 0x40) >> 6; - packet.header.res2 = (val & 0x20) >> 5; - packet.header.res3 = (val & 0x10) >> 4; - packet.header.rcode = (val & 0xF); -} -``` - -One effective way to check is to create a dns packet, pass it to -a custom packer and parser function and compare the input and output: - -```javascript -'use strict'; - -// order one http://www.binarytides.com/dns-query-code-in-c-with-linux-sockets/ -// order two http://www.zytrax.com/books/dns/ch15/ - -function parse(i) { - var header = { - // first byte appears to be reverse - qr: (i & 0x8000) >> 15 - , opcode: (i & 0x7800) >> 11 - , aa: (i & 0x400) >> 10 - , tc: (i & 0x200) >> 9 - , rd: (i & 0x100) >> 8 - - // second byte appears to be second byte, but also in reverse - , ra: (i & 0x80) >> 7 - , res1: (i & 0x40) >> 6 // z - , res2: (i & 0x20) >> 5 // ad - , res3: (i & 0x10) >> 4 // cd - , rcode: (i & 0x1F) - }; - - return header; -} - -function pack(header) { - var val = 0; - - val += (header.qr << 15) & 0x8000; - val += (header.opcode << 11) & 0x7800; - val += (header.aa << 10) & 0x400; - val += (header.tc << 9) & 0x200; - val += (header.rd << 8) & 0x100; - val += (header.ra << 7) & 0x80; - val += (header.res1 << 6) & 0x40; - val += (header.res2 << 5) & 0x20; - val += (header.res3 << 4) & 0x10; - val += header.rcode & 0x1F; - - return val; -} - -var start = { - qr: 1 -, opcode: 12 -, aa: 0 -, tc: 0 -, rd: 1 -, ra: 0 -, res1: 0 -, res2: 0 -, res3: 0 -, rcode: 0 -}; - -var i = pack(start); - -var obj = parse(i); - -console.log(i); -console.log(start); -console.log(obj); -// does a recursive check to see if start and obj are equal -require('assert').deepEqual(start, obj); - -``` - - - - -How to print out hex values of the DNS message in node.js? - -```javascript -socket.on('message', function (message, rinfo) { - console.log('Received %d bytes from %s:%d\n', - message.length, rinfo.address, rinfo.port); - //console.log(msg.toString('utf8')); - - console.log(message.toString('hex')); -``` - - - -DNS sec: security -puts a signature on a DNS packet and imprints a signature so that the sender of -the packet is confirmed