small DNS query tool in C. looks up different record types from the command line.
i wrote this mostly to understand how DNS actually works at the packet level. no libraries, just raw UDP sockets and manual packet construction/parsing.
needs gcc. windows only right now (winsock).
gcc main.c -o dnsquery -lws2_32dnsquery <hostname> [type] [-s server] [-v]record types: A (default), AAAA, CNAME, NS, MX, TXT
flags:
-s <server>— custom DNS server (default: 8.8.8.8)-v— verbose, dumps raw packet bytes-h— help
dnsquery google.com
dnsquery google.com AAAA
dnsquery google.com MX
dnsquery github.com NS
dnsquery _dmarc.google.com TXT
dnsquery google.com A -s 1.1.1.1
dnsquery google.com A -vDNS Query Tool
querying: gmail.com [MX]
server: 8.8.8.8
--- DNS Response ---
Questions: 1, Answers: 5, Authority: 0, Additional: 0
Type Name Value TTL
MX gmail.com 5 gmail-smtp-in.l.google.com 300
MX gmail.com 10 alt1.gmail-smtp-in.l.google.com 300
MX gmail.com 20 alt2.gmail-smtp-in.l.google.com 300
MX gmail.com 30 alt3.gmail-smtp-in.l.google.com 300
MX gmail.com 40 alt4.gmail-smtp-in.l.google.com 300
dns is just UDP on port 53. you send a packet with a header (random transaction ID, flags, section counts) and a question (the hostname encoded label-by-label, each chunk prefixed with its length, plus the record type you want).
the response comes back in the same format but with answers tacked on. the annoying part was name compression, domain names in responses can contain pointers back to earlier in the packet instead of repeating the full name. took me a bit to get that right.
- windows only (winsock). wouldn't be hard to port but i haven't bothered
- IPv6 addresses print fully expanded, no
::shortening - no TCP fallback for responses over 512 bytes
- RFC 1035 — the actual spec, surprisingly readable
- Beej's Guide to Network Programming