| 
									
										
										
										
											2017-10-09 12:39:46 -06: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 13:09:10 -06: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-06 20:53:03 -06:00
										 |  |  | (function () { | 
					
						
							|  |  |  | 'use strict'; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | var input = process.argv[2]; | 
					
						
							|  |  |  | var fs = require('fs'); | 
					
						
							|  |  |  | var nb = fs.readFileSync(input, null); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-10-09 01:51:13 -06:00
										 |  |  | var ab = nb.buffer.slice(nb.byteOffset, nb.byteOffset + nb.byteLength); | 
					
						
							| 
									
										
										
										
											2017-10-06 20:53:03 -06:00
										 |  |  | var dv = new DataView(ab); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | // read header
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | console.log(''); | 
					
						
							|  |  |  | console.log('//////////////////'); | 
					
						
							|  |  |  | console.log('//    HEADER    //'); | 
					
						
							|  |  |  | console.log('//////////////////'); | 
					
						
							|  |  |  | console.log(''); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-10-09 12:39:46 -06:00
										 |  |  | console.log(''); | 
					
						
							|  |  |  | console.log('byte index 0x00'); | 
					
						
							|  |  |  | console.log(''); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-10-06 20:53:03 -06:00
										 |  |  | console.log('id (int)', dv.getUint16(0)); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-10-09 01:51:13 -06:00
										 |  |  | var flags = dv.getUint16(2, false); | 
					
						
							|  |  |  | console.log('header 0x', flags.toString(16)); | 
					
						
							| 
									
										
										
										
											2017-10-06 20:53:03 -06:00
										 |  |  | var flagsstr = '' | 
					
						
							| 
									
										
										
										
											2017-10-09 01:51:13 -06: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-06 20:53:03 -06: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 01:51:13 -06:00
										 |  |  | var count; | 
					
						
							| 
									
										
										
										
											2017-10-06 20:53:03 -06:00
										 |  |  | 
 | 
					
						
							|  |  |  | console.log('qdcount', qdcount); | 
					
						
							|  |  |  | console.log('ancount', ancount); | 
					
						
							|  |  |  | console.log('nscount', nscount); | 
					
						
							|  |  |  | console.log('arcount', arcount); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-10-09 12:39:46 -06:00
										 |  |  | function unpackQuestionLabels(opts) { | 
					
						
							|  |  |  |   var dv = opts.dv; | 
					
						
							|  |  |  |   //var origTotal = opts.total;
 | 
					
						
							|  |  |  |   var total = opts.total; | 
					
						
							|  |  |  |   var len = opts.len; | 
					
						
							| 
									
										
										
										
											2017-10-09 01:51:13 -06:00
										 |  |  |   var qnames = []; | 
					
						
							|  |  |  |   var labelLen; | 
					
						
							| 
									
										
										
										
											2017-10-09 12:39:46 -06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-10-09 01:51:13 -06:00
										 |  |  |   while (true) { | 
					
						
							|  |  |  |     if (total >= len) { | 
					
						
							| 
									
										
										
										
											2017-10-09 13:48:54 -06: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 01:51:13 -06:00
										 |  |  |       break; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     labelLen = dv.getUint8(total, false); // additional count
 | 
					
						
							|  |  |  |     total += 1; | 
					
						
							|  |  |  |     if (!labelLen) { | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2017-10-09 13:48:54 -06: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 12:39:46 -06:00
										 |  |  |       console.log('Found a pointer to' | 
					
						
							|  |  |  |         + ' 0x' + pointer.toString(16) + ' (' + pointer + ')' | 
					
						
							|  |  |  |         + ' at byte index' | 
					
						
							|  |  |  |         + ' 0x' + leftPad(total.toString(16)) + ' (' + total + ')' | 
					
						
							| 
									
										
										
										
											2017-10-09 13:09:10 -06:00
										 |  |  |         //+ ' which back-references:'
 | 
					
						
							| 
									
										
										
										
											2017-10-09 12:39:46 -06:00
										 |  |  |       ); | 
					
						
							| 
									
										
										
										
											2017-10-09 13:09:10 -06:00
										 |  |  |       /* | 
					
						
							| 
									
										
										
										
											2017-10-09 12:39:46 -06: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 13:09:10 -06:00
										 |  |  |       */ | 
					
						
							| 
									
										
										
										
											2017-10-09 12:39:46 -06:00
										 |  |  |       //total += 1;
 | 
					
						
							|  |  |  |       opts.cp = true; | 
					
						
							|  |  |  |       qnames.push(unpackQuestionLabels({ dv: dv, total: pointer, len: len }).qname); | 
					
						
							|  |  |  |       total += 1; | 
					
						
							| 
									
										
										
										
											2017-10-09 01:51:13 -06:00
										 |  |  |       break; | 
					
						
							| 
									
										
										
										
											2017-10-09 12:39:46 -06: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 01:51:13 -06:00
										 |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return { | 
					
						
							|  |  |  |     total: total | 
					
						
							|  |  |  |   , qname: qnames.join('.') | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-10-09 12:39:46 -06: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 10:56:02 -06:00
										 |  |  | var q = { total: 12 }; | 
					
						
							|  |  |  | function mapChar(ch) { return JSON.stringify(String.fromCharCode(ch)) + '(' + ch + ')'; } | 
					
						
							| 
									
										
										
										
											2017-10-09 12:39:46 -06:00
										 |  |  | function leftPad(ch) { ch = ch.toString(); while (ch.length < 2) { ch = '0' + ch; } return ch; } | 
					
						
							| 
									
										
										
										
											2017-10-09 10:56:02 -06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-10-09 01:51:13 -06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-10-06 20:53:03 -06:00
										 |  |  | console.log(''); | 
					
						
							|  |  |  | console.log('//////////////////'); | 
					
						
							|  |  |  | console.log('//   QUESTION   //'); | 
					
						
							|  |  |  | console.log('//////////////////'); | 
					
						
							|  |  |  | console.log(''); | 
					
						
							| 
									
										
										
										
											2017-10-09 01:51:13 -06:00
										 |  |  | for (count = 0; count < qdcount; count += 1) { | 
					
						
							| 
									
										
										
										
											2017-10-09 10:56:02 -06:00
										 |  |  |   console.log(''); | 
					
						
							| 
									
										
										
										
											2017-10-09 12:39:46 -06:00
										 |  |  |   console.log('Question ' + (count + 1) + ' of ' + qdcount + ' (byte index: 0x' + leftPad(q.total.toString(16)) + ' ' + q.total + ')'); | 
					
						
							| 
									
										
										
										
											2017-10-09 01:51:13 -06:00
										 |  |  |   q = unpackQuestion(dv, q.total, ab.byteLength); | 
					
						
							|  |  |  |   console.log(''); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-10-09 13:09:10 -06: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 01:51:13 -06:00
										 |  |  | console.log(''); | 
					
						
							|  |  |  | console.log('//////////////////'); | 
					
						
							|  |  |  | console.log('//    ANSWER    //'); | 
					
						
							|  |  |  | console.log('//////////////////'); | 
					
						
							|  |  |  | console.log(''); | 
					
						
							|  |  |  | for (count = 0; count < ancount; count += 1) { | 
					
						
							| 
									
										
										
										
											2017-10-09 10:56:02 -06:00
										 |  |  |   console.log(''); | 
					
						
							| 
									
										
										
										
											2017-10-09 12:39:46 -06:00
										 |  |  |   console.log('Answer', count + 1, 'of', ancount + ' (byte index: 0x' + q.total.toString(16) + ' ' + q.total + ')'); | 
					
						
							| 
									
										
										
										
											2017-10-09 13:09:10 -06:00
										 |  |  |   unpackResourceRecord(dv, q, ab); | 
					
						
							| 
									
										
										
										
											2017-10-09 01:51:13 -06:00
										 |  |  |   console.log(''); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | console.log(''); | 
					
						
							|  |  |  | console.log('//////////////////'); | 
					
						
							|  |  |  | console.log('//   AUTHORITY  //'); | 
					
						
							|  |  |  | console.log('//////////////////'); | 
					
						
							|  |  |  | console.log(''); | 
					
						
							|  |  |  | for (count = 0; count < nscount; count += 1) { | 
					
						
							| 
									
										
										
										
											2017-10-09 10:56:02 -06:00
										 |  |  |   console.log(''); | 
					
						
							| 
									
										
										
										
											2017-10-09 12:39:46 -06:00
										 |  |  |   console.log('Authority', count + 1, 'of', nscount + ' (byte index: 0x' + q.total.toString(16) + ' ' + q.total + ')'); | 
					
						
							| 
									
										
										
										
											2017-10-09 13:09:10 -06:00
										 |  |  |   unpackResourceRecord(dv, q, ab); | 
					
						
							| 
									
										
										
										
											2017-10-09 10:56:02 -06:00
										 |  |  |   console.log(''); | 
					
						
							| 
									
										
										
										
											2017-10-09 01:51:13 -06:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | console.log(''); | 
					
						
							|  |  |  | console.log('//////////////////'); | 
					
						
							|  |  |  | console.log('//  ADDITIONAL  //'); | 
					
						
							|  |  |  | console.log('//////////////////'); | 
					
						
							|  |  |  | console.log(''); | 
					
						
							|  |  |  | for (count = 0; count < arcount; count += 1) { | 
					
						
							| 
									
										
										
										
											2017-10-09 10:56:02 -06:00
										 |  |  |   console.log(''); | 
					
						
							| 
									
										
										
										
											2017-10-09 12:39:46 -06:00
										 |  |  |   console.log('Additional', count + 1, 'of', arcount + ' (byte index: 0x' + q.total.toString(16) + ' ' + q.total + ')'); | 
					
						
							| 
									
										
										
										
											2017-10-09 13:09:10 -06:00
										 |  |  |   unpackResourceRecord(dv, q, ab); | 
					
						
							| 
									
										
										
										
											2017-10-09 01:51:13 -06:00
										 |  |  |   console.log(''); | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2017-10-06 20:53:03 -06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-10-09 12:39:46 -06:00
										 |  |  | console.log(''); | 
					
						
							|  |  |  | console.log('total bytes', dv.byteLength); | 
					
						
							|  |  |  | console.log('total bytes read', q.total); | 
					
						
							|  |  |  | console.log(''); | 
					
						
							| 
									
										
										
										
											2017-10-06 20:53:03 -06:00
										 |  |  | 
 | 
					
						
							|  |  |  | }()); |