2017-10-09 18:39:46 +00:00
|
|
|
#!/usr/bin/env node
|
|
|
|
|
|
|
|
// node bin/debug.js ../dig.js/blar.DOEsNteXiST.AJ.OnEal.DAplIE.me.any.0.bin
|
|
|
|
// node bin/debugd.js ../dig.js/blar.DOEsNteXiST.AJ.OnEal.DAplIE.me.any.0.bin
|
|
|
|
// dig @localhost -p 65053 ANY DOEsNteXiST.AJ.OnEal.DAplIE.me
|
2017-10-09 19:09:10 +00:00
|
|
|
// dd if=../dig.js/blar.DOEsNteXiST.AJ.OnEal.DAplIE.me.any.0.bin of=blar.DOEsNteXiST.AJ.OnEal.DAplIE.me.any.0.trunc.bin bs=1 count=78
|
2017-10-07 02:53:03 +00:00
|
|
|
(function () {
|
|
|
|
'use strict';
|
|
|
|
|
|
|
|
var input = process.argv[2];
|
|
|
|
var fs = require('fs');
|
|
|
|
var nb = fs.readFileSync(input, null);
|
|
|
|
|
2017-10-09 07:51:13 +00:00
|
|
|
var ab = nb.buffer.slice(nb.byteOffset, nb.byteOffset + nb.byteLength);
|
2017-10-07 02:53:03 +00:00
|
|
|
var dv = new DataView(ab);
|
|
|
|
|
|
|
|
//
|
|
|
|
// read header
|
|
|
|
//
|
|
|
|
console.log('');
|
|
|
|
console.log('//////////////////');
|
|
|
|
console.log('// HEADER //');
|
|
|
|
console.log('//////////////////');
|
|
|
|
console.log('');
|
|
|
|
|
2017-10-09 18:39:46 +00:00
|
|
|
console.log('');
|
|
|
|
console.log('byte index 0x00');
|
|
|
|
console.log('');
|
|
|
|
|
2017-10-07 02:53:03 +00:00
|
|
|
console.log('id (int)', dv.getUint16(0));
|
|
|
|
|
2017-10-09 07:51:13 +00:00
|
|
|
var flags = dv.getUint16(2, false);
|
|
|
|
console.log('header 0x', flags.toString(16));
|
2017-10-07 02:53:03 +00:00
|
|
|
var flagsstr = ''
|
2017-10-09 07:51:13 +00:00
|
|
|
+ 'qr ' + ((flags & 0x8000) >> 15) + ', '
|
|
|
|
+ 'opcode ' + ((flags & 0x7800) >> 11) + ', '
|
|
|
|
+ 'aa ' + ((flags & 0x400) >> 10) + ', '
|
|
|
|
+ 'tc ' + ((flags & 0x200) >> 9) + ', '
|
|
|
|
+ 'rd ' + ((flags & 0x100) >> 8) + ', '
|
|
|
|
+ 'ra ' + ((flags & 0x80) >> 7) + ', '
|
|
|
|
+ 'res1 ' + ((flags & 0x40) >> 6) + ', '
|
|
|
|
+ 'res2 ' + ((flags & 0x20) >> 5) + ', '
|
|
|
|
+ 'res3 ' + ((flags & 0x10) >> 4) + ', '
|
|
|
|
+ 'rcode ' + ((flags & 0xF));
|
2017-10-07 02:53:03 +00:00
|
|
|
console.log('(flags: ' + flagsstr);
|
|
|
|
|
|
|
|
var qdcount = dv.getUint16(4, false); // query count
|
|
|
|
var ancount = dv.getUint16(6, false); // answer count
|
|
|
|
var nscount = dv.getUint16(8, false); // authority count
|
|
|
|
var arcount = dv.getUint16(10, false); // additional count
|
2017-10-09 07:51:13 +00:00
|
|
|
var count;
|
2017-10-07 02:53:03 +00:00
|
|
|
|
|
|
|
console.log('qdcount', qdcount);
|
|
|
|
console.log('ancount', ancount);
|
|
|
|
console.log('nscount', nscount);
|
|
|
|
console.log('arcount', arcount);
|
|
|
|
|
2017-10-09 18:39:46 +00:00
|
|
|
function unpackQuestionLabels(opts) {
|
|
|
|
var dv = opts.dv;
|
|
|
|
//var origTotal = opts.total;
|
|
|
|
var total = opts.total;
|
|
|
|
var len = opts.len;
|
2017-10-09 07:51:13 +00:00
|
|
|
var qnames = [];
|
|
|
|
var labelLen;
|
2017-10-09 18:39:46 +00:00
|
|
|
|
2017-10-09 07:51:13 +00:00
|
|
|
while (true) {
|
|
|
|
if (total >= len) {
|
2017-10-09 19:48:54 +00:00
|
|
|
opts.trunc = true;
|
|
|
|
console.warn('');
|
|
|
|
console.warn('[WARNING] The label was truncated by byte length of message or rdata.');
|
|
|
|
console.warn('[WARNING] Depending on the Resource Record type, that may be a parse error.');
|
|
|
|
console.warn('');
|
2017-10-09 07:51:13 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
labelLen = dv.getUint8(total, false); // additional count
|
|
|
|
total += 1;
|
|
|
|
if (!labelLen) {
|
|
|
|
break;
|
|
|
|
}
|
2017-10-09 19:48:54 +00:00
|
|
|
if (labelLen >= 0xc0) {
|
|
|
|
// (11 000000 & whatever) signifies pointer
|
|
|
|
// (00 111111 & whatever) bitmask for potentially large pointer
|
|
|
|
// (00 000001 11111111) largest realistic pointer value (512 byte message size)
|
|
|
|
var pointer = ((labelLen & 0x3f) << 8) | dv.getUint8(total, false);
|
2017-10-09 18:39:46 +00:00
|
|
|
console.log('Found a pointer to'
|
|
|
|
+ ' 0x' + pointer.toString(16) + ' (' + pointer + ')'
|
|
|
|
+ ' at byte index'
|
|
|
|
+ ' 0x' + leftPad(total.toString(16)) + ' (' + total + ')'
|
2017-10-09 19:09:10 +00:00
|
|
|
//+ ' which back-references:'
|
2017-10-09 18:39:46 +00:00
|
|
|
);
|
2017-10-09 19:09:10 +00:00
|
|
|
/*
|
2017-10-09 18:39:46 +00:00
|
|
|
console.log('-4', dv.getUint8(pointer - 4, false));
|
|
|
|
console.log('-3', dv.getUint8(pointer - 3, false));
|
|
|
|
console.log('-2', dv.getUint8(pointer - 2, false));
|
|
|
|
console.log('-1', dv.getUint8(pointer - 1, false));
|
|
|
|
console.log(' 0', dv.getUint8(pointer + 0, false));
|
|
|
|
console.log('+1', dv.getUint8(pointer + 1, false));
|
|
|
|
console.log('+2', dv.getUint8(pointer + 2, false));
|
|
|
|
console.log('bytes near the pointer itself (not what it points to) are:');
|
|
|
|
console.log('-2', dv.getUint8(total - 2, false));
|
|
|
|
console.log('-1', dv.getUint8(total - 1, false));
|
|
|
|
console.log(' 0', dv.getUint8(total + 0, false));
|
|
|
|
console.log('+1', dv.getUint8(total + 1, false));
|
|
|
|
console.log('+2', dv.getUint8(total + 2, false));
|
|
|
|
console.log('+3', dv.getUint8(total + 3, false));
|
|
|
|
console.log('+4', dv.getUint8(total + 4, false));
|
2017-10-09 19:09:10 +00:00
|
|
|
*/
|
2017-10-09 18:39:46 +00:00
|
|
|
//total += 1;
|
|
|
|
opts.cp = true;
|
|
|
|
qnames.push(unpackQuestionLabels({ dv: dv, total: pointer, len: len }).qname);
|
|
|
|
total += 1;
|
2017-10-09 07:51:13 +00:00
|
|
|
break;
|
2017-10-09 18:39:46 +00:00
|
|
|
} else {
|
|
|
|
var i;
|
|
|
|
var label = '';
|
|
|
|
console.log('label len', labelLen);
|
|
|
|
for (i = 0; i < labelLen; i += 1) {
|
|
|
|
//console.log('total:', total, i);
|
|
|
|
label += String.fromCharCode(dv.getUint8(total + i, false));
|
|
|
|
}
|
|
|
|
total += label.length;
|
|
|
|
console.log('label:', label);
|
|
|
|
qnames.push(label);
|
2017-10-09 07:51:13 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return {
|
|
|
|
total: total
|
|
|
|
, qname: qnames.join('.')
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2017-10-09 18:39:46 +00:00
|
|
|
function unpackQuestion(dv, total, len) {
|
|
|
|
|
|
|
|
var result = unpackQuestionLabels({ dv: dv, total: total, len: len });
|
|
|
|
|
|
|
|
// leading length and (potentially) trailing null
|
|
|
|
console.log('QNAME (len ' + (result.total - total) + '):', result.qname, result.cp ? '(pointer)' : '');
|
|
|
|
console.log('QTYPE (len 2):', dv.getUint16(result.total, false));
|
|
|
|
result.total += 2;
|
|
|
|
console.log('QCLASS (len 2):', dv.getUint16(result.total, false));
|
|
|
|
result.total += 2;
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2017-10-09 16:56:02 +00:00
|
|
|
var q = { total: 12 };
|
|
|
|
function mapChar(ch) { return JSON.stringify(String.fromCharCode(ch)) + '(' + ch + ')'; }
|
2017-10-09 18:39:46 +00:00
|
|
|
function leftPad(ch) { ch = ch.toString(); while (ch.length < 2) { ch = '0' + ch; } return ch; }
|
2017-10-09 16:56:02 +00:00
|
|
|
|
2017-10-09 07:51:13 +00:00
|
|
|
|
2017-10-07 02:53:03 +00:00
|
|
|
console.log('');
|
|
|
|
console.log('//////////////////');
|
|
|
|
console.log('// QUESTION //');
|
|
|
|
console.log('//////////////////');
|
|
|
|
console.log('');
|
2017-10-09 07:51:13 +00:00
|
|
|
for (count = 0; count < qdcount; count += 1) {
|
2017-10-09 16:56:02 +00:00
|
|
|
console.log('');
|
2017-10-09 18:39:46 +00:00
|
|
|
console.log('Question ' + (count + 1) + ' of ' + qdcount + ' (byte index: 0x' + leftPad(q.total.toString(16)) + ' ' + q.total + ')');
|
2017-10-09 07:51:13 +00:00
|
|
|
q = unpackQuestion(dv, q.total, ab.byteLength);
|
|
|
|
console.log('');
|
|
|
|
}
|
|
|
|
|
2017-10-09 19:09:10 +00:00
|
|
|
function unpackResourceRecord(dv, q, ab) {
|
|
|
|
var _q = unpackQuestion(dv, q.total, ab.byteLength);
|
|
|
|
q.total = _q.total;
|
|
|
|
console.log('ttl (len 4):', dv.getUint32(q.total, false));
|
|
|
|
q.total += 4;
|
|
|
|
q.rdlength = dv.getUint16(q.total, false);
|
|
|
|
console.log('rdlen (len 2):', q.rdlength);
|
|
|
|
q.total += 2;
|
|
|
|
console.log('rrdata (len ' + q.rdlength + '):');
|
|
|
|
console.log([].slice.call(new Uint8Array(ab), q.total, q.total + q.rdlength).map(mapChar).join(' '));
|
|
|
|
q.total += q.rdlength;
|
|
|
|
console.log('');
|
|
|
|
}
|
|
|
|
|
2017-10-09 07:51:13 +00:00
|
|
|
console.log('');
|
|
|
|
console.log('//////////////////');
|
|
|
|
console.log('// ANSWER //');
|
|
|
|
console.log('//////////////////');
|
|
|
|
console.log('');
|
|
|
|
for (count = 0; count < ancount; count += 1) {
|
2017-10-09 16:56:02 +00:00
|
|
|
console.log('');
|
2017-10-09 18:39:46 +00:00
|
|
|
console.log('Answer', count + 1, 'of', ancount + ' (byte index: 0x' + q.total.toString(16) + ' ' + q.total + ')');
|
2017-10-09 19:09:10 +00:00
|
|
|
unpackResourceRecord(dv, q, ab);
|
2017-10-09 07:51:13 +00:00
|
|
|
console.log('');
|
|
|
|
}
|
|
|
|
|
|
|
|
console.log('');
|
|
|
|
console.log('//////////////////');
|
|
|
|
console.log('// AUTHORITY //');
|
|
|
|
console.log('//////////////////');
|
|
|
|
console.log('');
|
|
|
|
for (count = 0; count < nscount; count += 1) {
|
2017-10-09 16:56:02 +00:00
|
|
|
console.log('');
|
2017-10-09 18:39:46 +00:00
|
|
|
console.log('Authority', count + 1, 'of', nscount + ' (byte index: 0x' + q.total.toString(16) + ' ' + q.total + ')');
|
2017-10-09 19:09:10 +00:00
|
|
|
unpackResourceRecord(dv, q, ab);
|
2017-10-09 16:56:02 +00:00
|
|
|
console.log('');
|
2017-10-09 07:51:13 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
console.log('');
|
|
|
|
console.log('//////////////////');
|
|
|
|
console.log('// ADDITIONAL //');
|
|
|
|
console.log('//////////////////');
|
|
|
|
console.log('');
|
|
|
|
for (count = 0; count < arcount; count += 1) {
|
2017-10-09 16:56:02 +00:00
|
|
|
console.log('');
|
2017-10-09 18:39:46 +00:00
|
|
|
console.log('Additional', count + 1, 'of', arcount + ' (byte index: 0x' + q.total.toString(16) + ' ' + q.total + ')');
|
2017-10-09 19:09:10 +00:00
|
|
|
unpackResourceRecord(dv, q, ab);
|
2017-10-09 07:51:13 +00:00
|
|
|
console.log('');
|
|
|
|
}
|
2017-10-07 02:53:03 +00:00
|
|
|
|
2017-10-09 18:39:46 +00:00
|
|
|
console.log('');
|
|
|
|
console.log('total bytes', dv.byteLength);
|
|
|
|
console.log('total bytes read', q.total);
|
|
|
|
console.log('');
|
2017-10-07 02:53:03 +00:00
|
|
|
|
|
|
|
}());
|