dns

Look up DNS records yourself, with any server: dns.lookup("example.com", "MX") gives a list of record maps; dns.reverse(ip) finds the name behind an address; dns.servers() shows the resolvers this computer uses. It is a small pure-Python DNS client over UDP (TCP when the answer is big). Records have "name", "type", "ttl" and "value", plus fields per type (MX: priority, host; SRV: priority, weight, port, target; SOA: primary, mailbox, serial...).

This library sends DNS queries over the network, so it needs the TB app on your computer. The examples here show the code; run them with tb file.tb.

import dns

Example

Needs the TB app on your computer, so there is no Run button here.

import dns

for r in dns.lookup("example.com", "MX") {
  say(r.priority, r.host)
}
say(
  dns.lookup("example.com", "TXT").map(fn(r) {
    return r.value
  }),
)
say(dns.reverse("1.1.1.1", "1.1.1.1"))

Functions

lookup(name, type?, server?, options?)

returns list

The records of a name, like the A records of "example.com".

Arguments

  • type the kind of record (default: "A"). One of:
    • A, AAAA, MX, TXT, NS, CNAME, PTR, SOA, SRV or CAA
  • server an IP like "1.1.1.1", or "ip:port", or a list to try in turn (default: this computer's resolvers).

Options

  • timeout seconds to wait (default: 3).
  • tcp true to ask over TCP (default: false).
  • retries how many more tries after a failure (default: 1).

Results

  • An empty list means the name exists but has no such records.
  • A name that doesn't exist gives an error with reason "nxdomain".

Example

say(dns.lookup("example.com"))
say(dns.lookup("example.com", "MX"))
Visualizehow dns.lookup works

dns.lookup("example.com", "MX", "1.1.1.1") gives [{"name": "example.com", "type": "MX", "ttl": 3600, "data": "10 mail.example.com"}]

dns.lookup: your computer talking to another oneyour computerDNS server1.1.1.153dnssends: MX example.com?gets back: recordsname"example.com"type?"MX"result · listtypettldataMX360010 mail.exam…

Illustration: example values, drawn from what the function does.

query(name, type, server?, options?)

returns map

The full DNS answer. Use it when you want the authority section, or to see an nxdomain without an error.

Returns a map with

  • "status" "ok", "nxdomain", ...
  • "answers", "authority", "additional" lists of records.
  • "truncated", "authoritative", "recursion_available" true or false.
  • "server" the server that answered.
Visualizehow dns.query works

dns.query("no-such.example", "A", "8.8.8.8") gives {"status": "nxdomain", "answers": [], "authority": [{"type": "SOA"}], "server": "8.8.8.8"}

dns.query: your computer talking to another oneyour computerDNS server8.8.8.853dnssends: A no-such.example?gets back: full answername"no-such.example"type"A"result · mapstatus"nxdomain"answers[]authority[{"type": "SOA"}]server"8.8.8.8"

Illustration: example values, drawn from what the function does.

reverse(ip, server?, options?)

returns text

The host name an IP points back to (its PTR record), or nil when it has none.

Visualizehow dns.reverse works

dns.reverse("8.8.4.4", "1.1.1.1") gives "dns.google"

dns.reverse: your computer talking to another oneyour computerDNS server1.1.1.153dnssends: PTR 4.4.8.8.in-addr.arpa?gets back: a nameip"8.8.4.4"result · text"dns.google"

Illustration: example values, drawn from what the function does.

reverse_name(ip)

returns text

The PTR name for an address: reverse_name("8.8.4.4") is "4.4.8.8.in-addr.arpa".

Visualizehow dns.reverse_name works

dns.reverse_name("8.8.4.4") gives "4.4.8.8.in-addr.arpa"

dns.reverse_name: inputs flowing into the function and the resultip"8.8.4.4"dns.reverse_nameresult · text"4.4.8.8.in-addr.arpa"ip"192.168.1.10"dns.reverse_nameresult · text"10.1.168.192.in-addr.arpa"ip"2001:db8::1"dns.reverse_nameresult · text1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.8.b.d.0.1.0.0.2.ip6.arpa

Real result: worked out by running this example with TB while the site was built.

servers()

returns list

The DNS servers this computer is set up to use (from /etc/resolv.conf or the Windows registry). Empty when none can be found. lookup() then uses 1.1.1.1 and 8.8.8.8.

Visualizehow dns.servers works

dns.servers() gives ["192.168.1.1", "1.1.1.1"]

dns.servers: inputs flowing into the function and the resultthis computer's settings/etc/resolv.conf orthe Windows registrydns.serversresult · list"192.168.1.1""1.1.1.1"

No inputs: call it as it is.

Illustration: example values, drawn from what the function does.

is_name(x)

returns bool

True if x looks like a host name DNS could look up (letters, digits, dashes, dots).

Visualizehow dns.is_name works

dns.is_name("mail.example.com") gives true

dns.is_name: inputs flowing into the function and the resultx"mail.example.com"dns.is_nameresult · booltruex"bad name!"dns.is_nameresult · boolfalsex"localhost"dns.is_nameresult · booltrue

Real result: worked out by running this example with TB while the site was built.

Values

NameValueWhat it is
dns.types["A", "NS", "CNAME", "SOA", "PTR", "MX", "TXT", "AAAA", "SRV", "CAA", "ANY"]

The record types lookup() knows.

Visualizehow dns.types works

dns.types gives ["A", "NS", "CNAME", "SOA", "PTR", "MX", "TXT", "AAAA", "SRV", "CAA", "ANY"]

The value dns.typesdns.types"A""NS""CNAME""SOA""PTR""MX""TXT""AAAA""SRV""CAA""ANY"what it isThe record types lookup() knows.

No inputs: call it as it is.

Real value, read from TB while the site was built.

dns.fallback_servers["1.1.1.1", "8.8.8.8"]

Public resolvers used when the computer lists none.

Visualizehow dns.fallback_servers works

dns.fallback_servers gives ["1.1.1.1", "8.8.8.8"]

The value dns.fallback_serversdns.fallback_servers"1.1.1.1""8.8.8.8"what it isPublic resolvers used when the computerlists none.

No inputs: call it as it is.

Real value, read from TB while the site was built.