Public
Edited
Jan 22, 2024
1 fork
14 stars
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
edges = {
const seen = new Set();
const queue = [start];
const answers = new d3.InternSet([], ({ TTL, ...rest }) =>
JSON.stringify(rest)
); // ignore TTL differences
while (queue.length) {
const name = queue.shift();
if (seen.has(name)) continue;
seen.add(name);
for (const type of types(name)) {
const response = await query({ name, type });
for (const a of response.Answer ?? [{ name, type }]) {
answers.add(a);
switch (a.type) {
case 1: // a
case 28: { // aaaa
if (allowed.includes("ptr")) {
const data = invert(a.data);
answers.add({ name: a.data, type: "ptr?", data });
queue.push(data);
}
break;
}
case 5: // cname
case 12: // ptr
queue.push(a.data);
break;
case 15: {
// mx
const data = a.data.split(" ", 2)[1];
answers.add({ name: a.data, type: "mx?", data });
queue.push(data);
break;
}
}
}
yield answers;
}
}
}
Insert cell
types = (name) =>
d3.intersection(
allowed,
name.endsWith(".in-addr.arpa.") || name.endsWith("ip6.arpa.")
? ["ptr"]
: ["a", "aaaa", "mx"]
)
Insert cell
// https://www.iana.org/assignments/dns-parameters/dns-parameters.xhtml#dns-parameters-4
rr = (type) => ({ 1: "a", 5: "cname", 12: "ptr", 15: "mx", 28: "aaaa" }[type] ?? type)
Insert cell
query = (params) =>
fetch(`https://dns.google/resolve?${new URLSearchParams(params)}`).then(
(res) => res.ok ? res.json() : {}
)
Insert cell
invert = (ip) => {
const ipv4 = ip.match(/^(\d+)\.(\d+)\.(\d+)\.(\d+)\.?$/);
if (ipv4) {
return `${ipv4.slice(1).reverse().join(".")}.in-addr.arpa.`;
} else if (ip.match(/^[0-9a-f:]+$/)) {
return `${ip.match(/[0-9a-f]/g).reverse().join(".")}.ip6.arpa.`;
}
}
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more