'use strict'; var dnsjs = require('dns-suite'); var crypto = require('crypto'); var dgram = require('dgram'); var RCODES = { 0: 'NOERROR' , 3: 'NXDOMAIN' , 5: 'REFUSED' }; function logQuestion(packet) { var flags = ""; // TODO opcode 0 QUERY rcode 0 NOERROR console.info(';; ->>HEADER<<- [opcode: ' + packet.header.opcode + ', status: ' + (RCODES[packet.header.rcode] || packet.header.rcode) + '], id: ' + packet.header.id); if (packet.header.tc) { console.info("Truncated [tc] (we don't know the normal way to print a tc packet... you should record this with -o tc-packet.dig and send it to us)"); } flags += ";; flags:"; if (packet.header.qr) { flags += " qr"; } if (packet.header.aa) { flags += " aa"; } if (packet.header.rd) { flags += " rd"; } if (packet.header.ra) { flags += " ra"; } flags += "; QUERY: " + packet.question.length + ", ANSWER: " + packet.answer.length + ", AUTHORITY: " + packet.authority.length + ", ADDITIONAL: " + packet.additional.length; console.info(flags); if (packet.header.res1) { console.info("[res1] (we don't know how to print a packet with res1 yet)"); } if (packet.header.res2) { console.info("[res2] (we don't know how to print a packet with res2 yet)"); } if (packet.header.res3) { console.info("[res3] (we don't know how to print a packet with res2 yet)"); } // {"id":32736,"qr":1,"opcode":0,"aa":0,"tc":0,"rd":1,"ra":0,"res1":0,"res2":0,"res3":0,"rcode":5} //console.log(JSON.stringify(packet.header)); console.info(''); console.info(';; QUESTION SECTION:'); packet.question.forEach(function (q) { console.info(';' + q.name + '.', ' ', q.className, q.typeName || ('type' + q.type)); }); } function resolve(queryAb, opts) { var handlers = {}; var nameservers; var nameserver = opts.nameserver; var index; var udpType; var receivedMessage; if (!nameserver) { nameservers = require('dns').getServers(); index = crypto.randomBytes(2).readUInt16BE(0) % nameservers.length; nameserver = nameservers[index]; } udpType = /:/.test(nameserver) ? 'udp6' : 'udp4'; var server = dgram.createSocket({ type: udpType , reuseAddr: true }); server.nameserver = nameserver; handlers.onError = function (err) { if (opts.onError) { opts.onError(err); } else { throw err; } server.close(); }; handlers.onMessage = function (bin) { receivedMessage = true; if (!opts.mdns) { clearTimeout(server._timeoutToken); server.close(); } if (opts.onMessage) { opts.onMessage(bin); } }; handlers.onListening = function () { /*jshint validthis:true*/ var server = this; if (opts.mdns || '224.0.0.251' === server.nameserver) { server.setBroadcast(true); server.addMembership(server.nameserver || '224.0.0.251'); } if (opts.onListening) { opts.onListening.apply(server); } server.send(Buffer.from(queryAb), opts.port, server.nameserver, function () { if (opts.onSent) { opts.onSent({ port: opts.port, nameserver: server.nameserver }); } }); }; handlers.onClose = function () { if (opts.onClose) { opts.onClose(); } }; server.on('error', handlers.onError); server.on('message', handlers.onMessage); server.on('listening', handlers.onListening); server.on('close', handlers.onClose); // 0 dns request // 53 dns server // 5353 mdns if (opts.mdns) { server.bind(opts.port /*5353*/); } else { server.bind(0); } var ms = opts.timeout || (5 * 1000); server._timeoutToken = setTimeout(function () { if (!receivedMessage && opts.onTimeout) { opts.onTimeout({ timeout: ms }); } server.close(); }, ms); } function resolveJson(query, opts) { var queryAb; try { queryAb = dnsjs.DNSPacket.write(query); } catch(e) { if ('function' === typeof opts.onError) { opts.onError(e); return; } throw e; } //console.log('[DEV] nameserver', opts.nameserver); var options = { onError: opts.onError , onMessage: function (nb) { var packet; try { packet = dnsjs.DNSPacket.parse(nb.buffer.slice(nb.byteOffset, nb.byteOffset + nb.byteLength)); } catch(e) { if (opts.onError) { opts.onError(e); return; } console.error("[Error] couldn't parse incoming message"); console.error(e); return; } opts.onMessage(packet); } , onListening: opts.onListening , onSent: opts.onSent , onClose: opts.onClose , onTimeout: opts.onTimeout , mdns: opts.mdns , nameserver: opts.nameserver , port: opts.port , timeout: opts.timeout }; return resolve(queryAb, options); } module.exports.resolve = resolve; module.exports.resolveJson = resolveJson; module.exports.request = resolve; module.exports.requestJson = resolveJson; module.exports.logQuestion = logQuestion;