#!/usr/bin/env node 'use strict'; // EXAMPLE: // node bin/dns-parse.js samples/a-0.mdns.bin var path = require('path'); // pass a terminal arg var filename = process.argv[2]; var outname = process.argv[3]; if (!filename || /(-h)|(--help)/.test(process.argv.join(' '))) { console.error(""); console.error("Accepts a DNS packet (binary or json), converts it, and then converts it back to verify the function of the parser and packer"); console.error(""); console.error("Usage: node bin/dns-test.js "); console.error("Example: node bin/dns-test.js ./samples/services-0.mdns.json ./samples/services-0.mdns.bin"); process.exit(1); return; } var PromiseA = require('bluebird'); var fs = PromiseA.promisifyAll(require('fs')); var dnsjs = require('../').DNSPacket; var extname = path.extname(filename).substr(1).toLowerCase(); if ('json' !== extname && 'bin' !== extname) { console.error("The file extension must end in .json or .bin (raw DNS packet)"); process.exit(3); return; } var hexdump = require('hexdump.js').hexdump; function testJsonAsync(nb) { var packet = dnsjs.write(JSON.parse(nb.toString('ascii'))); var str = hexdump(packet); console.info(str); var json = dnsjs.parse(packet); if (json.error) { console.error(json); process.exit(37); return; } console.info("[OK] JSON -> binary -> JSON"); if (!outname) { console.warn(''); console.warn( "Usage: node bin/dns-test.js '" + filename + "' './" + path.basename(filename).replace(path.extname(filename), '.bin') + "'" ); console.warn(''); return; } fs.writeFileSync(outname, packet, null); } function testBinAsync(nb) { var bin = nb.buffer.slice(nb.byteOffset, nb.byteOffset + nb.byteLength); var json = dnsjs.parse(bin); if (json.error) { console.error(json); process.exit(38); return; } var bin2 = dnsjs.write(json); //var debugname = outname || path.basename(filename); //fs.writeFileSync(debugname.replace(path.extname(debugname), '.bin'), bin2, null); var json2 = dnsjs.parse(bin2); if (json2.error) { console.error(json2); process.exit(37); return; } var assert = require('assert'); // EXPLANATION: // The strategy used for compression pointers has not yet been proven // as deterministic... and we don't implement them anyway, so this may not be the same json = JSON.parse(JSON.stringify(json) .replace(/,"labels":.*?\]/, '') .replace(/,"cpcount":\d+/, '') ); json2 = JSON.parse(JSON.stringify(json2) .replace(/,"labels":.*?\]/, '') .replace(/,"cpcount":\d+/, '') ); //json2 = JSON.parse(JSON.stringify(json2)); try { assert.deepEqual(json, json2); } catch(e) { console.error(''); console.error('Original'); console.error(JSON.stringify(json, null, 2)); console.error(''); console.error('Converted'); console.error(JSON.stringify(json2, null, 2)); console.error(''); process.exit(422); return; } console.info("[OK] binary -> JSON -> binary -> JSON"); console.warn("(compression pointer support needs to be improved in order to support direct bin -> JSON -> bin testing)"); if (!outname) { console.warn(''); console.warn( "Usage: node bin/dns-test.js '" + filename + "' './" + path.basename(filename).replace(path.extname(filename), '.json') + "'" ); console.warn(''); return; } fs.writeFileSync(outname, JSON.stringify(json, null, 2), null); } if ('json' === extname) { return fs.readFileAsync(filename, null).then(testJsonAsync); } if ('bin' === extname) { return fs.readFileAsync(filename, null).then(testBinAsync); }