Skip to content

Instantly share code, notes, and snippets.

@simonster
Last active August 29, 2015 14:24
Show Gist options
  • Save simonster/f2cc51584ae5f8709e70 to your computer and use it in GitHub Desktop.
Save simonster/f2cc51584ae5f8709e70 to your computer and use it in GitHub Desktop.
if (platform == "win") {
libc = ctypes.open("Ws2_32.dll");
var dnsapi = ctypes.open("Dnsapi.dll");
var DNS_RECORD = new ctypes.StructType("DNS_RECORD");
DNS_RECORD.define([{"pNext":DNS_RECORD.ptr}, {"pName":ctypes.char.ptr}, {"wType":ctypes.unsigned_short},
{"wDataLength":ctypes.unsigned_short}, {"DW":ctypes.unsigned_long}, {"dwTtl":ctypes.unsigned_long},
{"dwReserved":ctypes.unsigned_long}, {"pNameHost":ctypes.char.ptr}]);
var DnsQuery = dnsapi.declare("DnsQuery_A", ctypes.winapi_abi, ctypes.int, ctypes.char.ptr, ctypes.unsigned_short,
ctypes.unsigned_long, ctypes.voidptr_t, DNS_RECORD.ptr, ctypes.voidptr_t);
var DnsRecordListFree = dnsapi.declare("DnsRecordListFree", ctypes.winapi_abi, ctypes.void_t, DNS_RECORD.ptr,
ctypes.int);
var record = new DNS_RECORD();
var getIPForLookup = function(ip) {
if (ip.indexOf(".") != -1) {
// IPv4
x = ip.split(".").reverse().join(".")+".in-addr.arpa";
} else {
if (ip.indexOf("%") != -1) ip = ip.substr(0, ip.indexOf("%"));
// IPv6
var parts = ip.split(":");
x = "ip6.arpa"
for (var i = 0; i < parts.length; i++) {
var part = parts[i];
for (var j = 0; j < (part.length == 0 ? 4*(9-parts.length) : 4-part.length); j++) x = "0." + x;
for (var j = 0; j < part.length; j++) x = part[j] + "." + x;
}
}
return x;
}
var reverseLookup = function(ip) {
var status = DnsQuery(getIPForLookup(ip), 12 /*DNS_TYPE_PTR*/, 32 /*DNS_QUERY_NO_LOCAL_NAME*/, null, record.address(), null);
if (status != 0 || record.pNext.isNull()) return null;
var retval = record.pNext.contents.pNameHost.readString();
DnsRecordListFree(record.pNext, 1);
return retval;
};
} else if (platform == "mac") {
libc = ctypes.open("libc.dylib");
} else {
var possibleLibcs = [
"libc.so.6",
"libc.so.6.1",
"libc.so"
];
for(var i = 0; i < possibleLibcs.length; i++) {
try {
libc = ctypes.open(possibleLibcs[i]);
break;
} catch(e) {}
}
}
var sockaddr = new ctypes.StructType("sockaddr");
var addrinfo = new ctypes.StructType("arrinfo");
addrinfo.define([{"ai_flags":ctypes.int}, {"ai_family":ctypes.int}, {"ai_socktype":ctypes.int},
{"ai_protocol":ctypes.int}, {"ai_addrlen":ctypes.int}, {"ai_canonname":ctypes.char.ptr},
{"ai_addr":sockaddr.ptr}, {"ai_next":addrinfo.ptr}]);
var gethostname = libc.declare("gethostname", ctypes.default_abi, ctypes.int, ctypes.char.ptr, ctypes.size_t);
var getaddrinfo = libc.declare("getaddrinfo", ctypes.default_abi, ctypes.int, ctypes.char.ptr, ctypes.char.ptr,
addrinfo.ptr, addrinfo.ptr.ptr);
var freeaddrinfo = libc.declare("freeaddrinfo", ctypes.default_abi, ctypes.void_t, addrinfo.ptr);
var getnameinfo = libc.declare("getnameinfo", ctypes.default_abi, ctypes.int, sockaddr.ptr, ctypes.int,
ctypes.char.ptr, ctypes.int, ctypes.char.ptr, ctypes.int, ctypes.int);
var buf = new new ctypes.ArrayType(ctypes.char, 1025);
var status = gethostname(buf, 1025);
if (status != 0) throw new Error("could not get hostname: "+status);
var hosts = [];
var hints = new addrinfo();
if (platform != "win") hints.ai_flags = 2;
var out = new addrinfo.ptr();
status = getaddrinfo(buf, null, hints.address(), out.address());
if (status != 0) throw new Error("could not get addrinfo: "+status);
var rec = out;
try {
if (platform == "win") {
while (!rec.isNull()) {
status = getnameinfo(rec.contents.ai_addr, rec.contents.ai_addrlen, buf, 1025, null, 0, 2);
if (status != 0) throw new Error("could not get IP address: "+status);
var host = reverseLookup(buf.readString());
if (host) hosts.push(host);
rec = rec.contents.ai_next;
}
} else {
// Not perfect, but need to figure out the right API to do a
// proper query
while (!rec.isNull()) {
if (!rec.contents.ai_canonname.isNull()) hosts.push(rec.contents.ai_canonname.readString());
rec = rec.contents.ai_next;
}
}
} finally {
freeaddrinfo(out);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment