155 lines
4.7 KiB
JavaScript
155 lines
4.7 KiB
JavaScript
'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;
|