A lightweight shell script for OpenWrt routers to dump and display the dnsmasq DNS cache in a clean, formatted table. Works with basic busybox/ash environment.
- Triggers dnsmasq cache dump via SIGUSR1
- Extracts and formats the most recent cache dump from logs
- Displays cache statistics (queries, memory usage, server stats)
- Works with OpenWrt's ujail-wrapped dnsmasq processes
- OpenWrt router with dnsmasq
- Dnsmasq logging enabled (
log-queriesoption) - Log file at
/var/log/dnsmasq(or modifyLOGFILEvariable) - Busybox/ash shell environment
- In my testing, even with a large 8000-item cache, all the lines dumped to the logfile had the same timestamp. Thus, the script assumes the dump lines will be prefixed with the same timestamp. This may not be the case for older, slower systems or larger caches.
- Also in my testing, the other lines in the log files, before and after the dump, always had different timestamps. Thus, the script assumes there won't be any extraneous lines with the same timestamp as the dump lines. This may not be the case in newer, faster systems or systems that are very busy. Good luck!
- It is assumed that SIGUSR1 has already been sent to the dnsmasq process. A helper command for that is provided below.
- Copy
show_dnsmasq_cache.shto your OpenWrt router (e.g.,/usr/bin/) - Make it executable:
chmod +x /usr/bin/show_dnsmasq_cache.shkill -USR1 $(pidof dnsmasq | awk '{print $1}')show_dnsmasq_cache.shIf you have the Custom Commands package installed, you can add these as buttons in the web interface:
opkg update
opkg install luci-app-commandsNavigate to: System → Custom Commands → Configure → Add
- Description:
Dump DNS Cache - Command:
sh -c 'kill -USR1 $(pidof dnsmasq | awk "{print \$1}")' - Custom arguments: Could be helpful for targeting different PID's? Leave off until you come up with something.
- Public access: Recommend leaving this off.
- Description:
Show DNS Cache - Command:
show_dnsmasq_cache.sh - Custom arguments: Enable. Could be helpful for parsing the output further, for example looking for specific domain.
- Public access: Also recommend leaving this off.
Usage Flow:
- Click "Dump DNS Cache" button (wait ~1 second)
- Click "Show DNS Cache" button to view the formatted output
(I have dnsmasq configured to forward to local DNS Proxy for Adguard DoQ/DoT/DoH)
Dnsmasq cache stat's & contents as of: Nov 2 11:00:10
time 1762106410
cache size 4000, 0/905 cache insertions re-used unexpired cache entries.
queries forwarded 376, queries answered locally 732
pool memory in use 1540, max 5412, allocated 6600
child processes for TCP requests: in use 0, highest since last SIGUSR1 0, max allowed 20.
server 127.0.0.1#5354: queries sent 347, retried 0, failed 3, nxdomain replies 26, avg. latency 62ms
server ::1#5354: queries sent 138, retried 0, failed 2, nxdomain replies 2, avg. latency 258ms
Host Address Flags Expires Source
------------------------------ ---------------------------------------- ---------- ------------------------ ------------
example.com 93.184.216.34 4F Wed Nov 5 11:00:10 2025
www.example.com example.com CF Wed Nov 5 11:00:10 2025
ipv6.example.com 2606:2800:220:1:248:1893:25c8:1946 6F Wed Nov 5 11:00:10 2025
_http._tcp.example.com <SRV> TF Wed Nov 5 11:00:10 2025
zazu.lan 192.168.1.9 4FR D Mon Nov 3 02:25:25 2025
zazu.lan 2600:d0d0:15:dead::123 6FRI H /tmp/hosts/odhcpd
zazu.lan b16:bad:b1d1::123 6FRI H /tmp/hosts/odhcpd
- Host: The queried hostname
- Address: IP address, CNAME target, or special value (e.g.,
<SRV>,<HTTPS>) - Flags: Cache entry flags
- 4 - IPv4 address
- 6 - IPv6 address
- C - CNAME
- F - forward (name->address) mapping
- R - reverse (address->name) mapping
- I - immortal (no expiry time)
- D - originates from DHCP
- N - negative (name known not to have address)
- X - no such domain (name known not to exist)
- H - originates from /etc/hosts.
- Expires: Expiration date/time of the cache entry
- Source: Source of the DNS record (if applicable)
- Ensure dnsmasq logging is enabled in
/etc/config/dhcp:option logqueries '1' - Verify log file location matches
LOGFILEvariable in script - Manually trigger cache dump:
killall -USR1 dnsmasq - Check log file:
tail /var/log/dnsmasq
- The script automatically targets only the actual dnsmasq process (not the ujail wrapper)
- If issues persist, check PIDs:
pidof dnsmasq
- Check that your dnsmasq version outputs standard cache dump format
- Signal dnsmasq: Sends SIGUSR1 to the dnsmasq process to trigger cache dump
- Find latest dump: Searches for the most recent "time" line in the log
- Extract timestamp: Preserves exact syslog timestamp format (handles single-digit days)
- Filter logs: Uses grep to extract only lines matching that timestamp
- Format output: Removes syslog prefix while preserving column spacing
OpenWrt's Custom Commands interface aggressively quotes command arguments, breaking pipes and command substitution. Wrapping in sh -c forces the entire command to be executed as a single shell string.
show_dnsmasq_cache.sh- Main script to display formatted cacheREADME.md- This file
Public domain
Found a bug or have an improvement? Feel free to modify and share!
Tested and developed on OpenWrt 24.10 in busybox/ash environment by scarlion1@GitHub, with assistance from Claude Sonnet 4.5 provided by Abacus.AI. Check them out for affordable, unparalleled services and access to every LLM for only $10/mo. Use my referral link https://chatllm.abacus.ai/YwBngMwYCw and I'll give you a cookie.