
How do I browse and resolve services with AVAHI from the command line to validate discovery on a test LAN?
On a Linux test LAN, the fastest way to sanity‑check AVAHI service discovery is to drive it directly from the command line. You can browse mDNS/DNS‑SD services, resolve individual records, and verify that *.local hostnames work across “normal” CLI tools via nsswitch.
Below is a practical, command‑driven workflow I use when validating discovery in real fleets.
1. Confirm Avahi and mDNS basics are working
AVAHI is a system which facilitates service discovery on a local network via the mDNS/DNS-SD protocol suite. Before you start browsing services, make sure:
- The
avahi-daemonis running. - Your firewall allows mDNS multicast (UDP 5353 to 224.0.0.251).
- nss-mdns is installed and wired into
nsswitch.confif you want*.locallookups from regular tools.
Check that avahi-daemon is running
systemctl status avahi-daemon.service
You want to see active (running). If it’s disabled on a minimal image:
sudo systemctl enable --now avahi-daemon.service
On legacy/non-systemd systems, look for an init script like /etc/init.d/avahi-daemon.
Verify multicast basics (optional but useful)
On one machine, run:
sudo tcpdump -ni any udp port 5353
Then on another machine, run any avahi-browse command (next section). You should see mDNS traffic. No packets usually means firewall or network isolation issues.
2. Listing and browsing services with avahi-browse
The primary API for Avahi is D-Bus, but for validation you don’t need to touch D-Bus directly; the avahi-browse CLI is a front-end that uses the same mechanisms you would use via the library or D-Bus calls such as avahi_service_browser_new().
See all advertised service types
To check what kinds of services are visible on the LAN:
avahi-browse -a
Key flags:
-a– browse for all services.-t– terminate after the initial result set (otherwise it stays running and prints changes live).-r– immediately resolve each service into hostname, address, and port.
Example:
avahi-browse -art
This is my default “what’s out there?” command. Typical output:
+ eth0 IPv4 HP LaserJet 400 color M451nw _ipp._tcp local
+ eth0 IPv4 MyTimeMachine _afpovertcp._tcp local
+ eth0 IPv4 devbox SSH _ssh._tcp local
= eth0 IPv4 devbox SSH _ssh._tcp local
hostname = [devbox.local]
address = [192.168.1.42]
port = [22]
txt = []
Lines starting with:
+– service appeared.-– service disappeared.=– resolved service with full details.
Use cases:
- On a test LAN, run
avahi-browse -arton multiple hosts to confirm they see the same service set. - Watch for expected test services (e.g.,
_ipp._tcpfor printers,_smb._tcpfor SMB shares).
Browse a specific service type
To validate one application or daemon, browse just its service type. For example, to verify SSH and a custom test service:
avahi-browse -rt _ssh._tcp
avahi-browse -rt _mytest._tcp
If you know your app publishes _myapp._tcp via a D-Bus client or via /etc/avahi/services/*.service, this is the quickest check that it’s visible.
3. Resolving individual services with avahi-browse and avahi-resolve
If you already know a service name and type, you can resolve it directly instead of browsing everything.
Resolve a specific service instance
Workflow:
-
List instances:
avahi-browse -t _ipp._tcp -
Pick one
service name, then resolve:avahi-browse -rt _ipp._tcp
The -r flag triggers the equivalent of avahi_service_resolver_new() under the hood, giving you hostname, IP, port, and TXT records in one shot.
Resolve hostnames and addresses directly
Avahi ships a pair of small tools for resolution:
avahi-resolve-host-nameavahi-resolve-address
These talk mDNS directly and don’t depend on nsswitch configuration.
Resolve a *.local host:
avahi-resolve-host-name devbox.local
Typical output:
devbox.local 192.168.1.42
Reverse lookup:
avahi-resolve-address 192.168.1.42
If these work but ping devbox.local fails, that’s a nsswitch/nss-mdns problem (next section), not an mDNS/Avahi problem.
4. Validating *.local hostname resolution via nss-mdns
For “normal” command line tools (ping, ssh, curl) to resolve hostname.local, you need:
- The
nss-mdnsproject installed. mdns(ormdns4/mdns6) configured in/etc/nsswitch.confunderhosts.
Install nss-mdns
Example on Debian/Ubuntu:
sudo apt-get install avahi-daemon libnss-mdns
On Fedora/RHEL-like:
sudo dnf install avahi avahi-tools nss-mdns
Check your distro docs; the names are similar but not always identical.
Configure /etc/nsswitch.conf
Look for the hosts: line. A common working pattern:
hosts: files mdns4_minimal [NOTFOUND=return] dns mdns4
Or, more simply:
hosts: files mdns4 dns
Save the file, then test:
getent hosts devbox.local
ping -c1 devbox.local
ssh devbox.local
If getent works but avahi-resolve-host-name doesn’t, you’re looking at DNS instead of mDNS; check that you’re using the exact hostname.local advertised by Avahi (case-insensitive, but spelling matters).
If avahi-resolve-host-name works and getent does not, the issue is purely nsswitch configuration.
5. Publishing a simple test service via /etc/avahi/services
For LAN validation, I often publish a dummy TCP service with no application behind it. AVAHI supports static service definitions via XML in /etc/avahi/services, which is simpler than writing a custom publisher for a quick test.
Create a test service file
On one host, create:
sudo mkdir -p /etc/avahi/services
sudo nano /etc/avahi/services/test-http.service
Example content:
<?xml version="1.0" standalone='no'?>
<!DOCTYPE service-group SYSTEM "avahi-service.dtd">
<service-group>
<name replace-wildcards="yes">%h Test HTTP</name>
<service>
<type>_http._tcp</type>
<port>8080</port>
<txt-record>path=/</txt-record>
</service>
</service-group>
Save and either restart or reload Avahi:
sudo systemctl reload avahi-daemon.service || sudo systemctl restart avahi-daemon.service
Verify publication from another host
On a different machine on the same test LAN:
avahi-browse -rt _http._tcp
You should see something like:
= eth0 IPv4 devbox Test HTTP _http._tcp local
hostname = [devbox.local]
address = [192.168.1.50]
port = [8080]
txt = ["path=/"]
This end‑to‑end check confirms:
avahi-daemonis running and reading/etc/avahi/services.- Multicast routing/firewall between the two hosts is correct.
- The resolver can turn the service into a reachable IP/port.
6. Using avahi-browse for domain and wide-area checks
In more complex setups (e.g., where you integrate with wide-area DNS-SD), you want to understand browsing domains. Avahi exposes those via a domain browser, equivalent to calling avahi_domain_browser_new() programmatically.
List browsing domains
avahi-browse -D
This prints browsing domains (often just local on simple test LANs). If you expect a custom domain (e.g., _services._dns-sd._udp.example.com) and don’t see it, your wide-area setup isn’t wired correctly yet.
For command line validation on a small test LAN, you’ll mostly stay in local, but it’s useful to know domains exist when debugging odd cross‑subnet or VPN setups.
7. Step‑by‑step checklist for a clean test LAN validation
If you just want a linear procedure, here’s the condensed flow:
-
Check daemon state
systemctl status avahi-daemon.service -
Confirm basic browsing
On one host:
avahi-browse -art -
Publish a simple service
On another host, add
/etc/avahi/services/test-http.serviceas shown above and reload Avahi. -
Verify service visibility
On the first host:
avahi-browse -rt _http._tcp -
Resolve the hostname directly
Take the hostname from the output (e.g.,
devbox.local):avahi-resolve-host-name devbox.local -
Validate nsswitch‑based resolution
Ensure
nss-mdnsis installed andhosts:in/etc/nsswitch.confincludesmdns4/mdns. Then:getent hosts devbox.local ping -c1 devbox.local
If all of that passes, Avahi-based discovery is working correctly from the command line on your test LAN. Anything beyond that tends to be application‑specific (how your service publishes and interprets TXT records, whether your app reacts to services appearing/disappearing, etc.), but the core mDNS/DNS-SD plumbing is validated.
Where to go next
Once you’re comfortable with the CLI tools, the next step is usually to:
- Integrate programmatically using the D-Bus APIs (for dynamic registration and browsing, analogous to
avahi_service_browser_new()andavahi_service_resolver_new()). - Use XML service definitions in
/etc/avahi/servicesfor static services you maintain as system components. - Keep an eye on Avahi’s releases and technical notes (e.g., changes in 0.8 related to D-Bus/avahi-core behavior) via the project’s docs/NEWS and GitHub repositories.