#!/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('@root/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); }