I do not have an AirPrint printer on my network. And never played with one either...
I cannot test with a real AirPrint device in my proximity right now.
But here is how I can list all the IPP-enabled printers (in this case they are all connected via CUPS):
First, browse for DNS-SD discoverable services (all types):
kp@zdv-wireless-43-219:> dns-sd -B _services._dns-sd._udp local.
Browsing for _services._dns-sd._udp.local.
DATE: ---Fri 20 May 2016---
23:54:37.797 ...STARTING...
Timestamp A/R Flags if Domain Service Type Instance Name
23:54:37.798 Add 3 4 . _tcp.local. _ssh
23:54:37.798 Add 3 4 . _tcp.local. _sftp-ssh
23:54:37.798 Add 3 4 . _tcp.local. _airplay
23:54:37.798 Add 3 4 . _tcp.local. _raop
23:54:37.798 Add 3 4 . _tcp.local. _googlecast
23:54:37.798 Add 3 4 . _tcp.local. _nomachine
23:54:37.798 Add 3 4 local. _apple-mobdev2._tcp. _sub
23:54:37.798 Add 3 4 . _tcp.local. _apple-mobdev2
23:54:37.798 Add 3 4 . _tcp.local. _ipps
23:54:37.798 Add 3 4 . _tcp.local. _ipp
23:54:37.798 Add 3 4 . _tcp.local. _workstation
23:54:37.798 Add 3 4 . _tcp.local. _http
23:54:37.798 Add 3 4 . _tcp.local. _amzn-wplay
23:54:37.798 Add 3 4 . _tcp.local. _rfb
23:54:37.798 Add 3 4 . _tcp.local. _afpovertcp
23:54:37.798 Add 3 4 . _tcp.local. _smb
23:54:37.798 Add 3 4 . _udp.local. _net-assistant
23:54:37.798 Add 2 4 . _tcp.local. _eppc
^C
So yes, there is indeed an IPP print service (but no AirPrint one, which would be marked by stand out being tagged as Service Type of _airprint._tcp
in the list).
Second, browse for all present services of type "IPP":
kp@zdv-wireless-43-219:> dns-sd -B _ipp._tcp local.
Browsing for _ipp._tcp.local.
DATE: ---Fri 20 May 2016---
23:54:47.782 ...STARTING...
Timestamp A/R Flags if Domain Service Type Instance Name
23:54:47.783 Add 3 4 local. _ipp._tcp. Officejet6500donna @ mbp
23:54:47.783 Add 3 4 local. _ipp._tcp. raw2dir @ mbp
23:54:47.783 Add 2 4 local. _ipp._tcp. Officejet 6600 @ mbp
^C
Ok, one of the instance names is "Officejet 6600 @ mbp".
Third, lookup specific info about the printer named "Officejet 6600 @ mbp":
kp@zdv-wireless-43-219:> dns-sd -L "Officejet 6600 @ mbp" _ipp._tcp local.
Lookup Officejet 6600 @ mbp._ipp._tcp.local.
DATE: ---Fri 20 May 2016---
23:54:55.252 ...STARTING...
23:54:55.253 Officejet\0326600\032@\032mbp._ipp._tcp.local. can be reached at mbp2-2.local.:631 (interface 4)
txtvers=1 qtotal=1 rp=printers/Officejet_6600 ty=Unknown \
adminurl=https://mbp2-2.local.:631/printers/Officejet_6600 \
note=Büro\ im\ Keller priority=0 product=\(Officejet\ 6600\ e-All-in-One\) \
pdl=application/octet-stream,application/pdf,application/postscript,image/jpeg,image/png,image/pwg-raster \
UUID=e7d11337-a440-3f2d-7168-b53de4325791 TLS=1.2 Color=T Scan=T \
printer-state=3 printer-type=0x480900E
^C
Half of the info you are looking for (hostname of the printer) is covered by the sentence "Officejet\0326600\032@\032mbp._ipp._tcp.local. can be reached at mbp2-2.local.:631"
This gives the current (Bonjour-)hostname of node offering the looked-up print service.
Fourth, look up the IPv4 and IPv6 addresses for a given hostname:
kp@zdv-wireless-43-219:> dns-sd -Gv4v6 mbp2-2.local
DATE: ---Sat 21 May 2016---
0:12:41.025 ...STARTING...
Timestamp A/R Flags if Hostname Address TTL
0:12:41.025 Add 3 4 mbp2-2.local. FE80:0000:0000:0000:AEBC:32FF:FEAE:CAEB%en0 120
0:12:41.025 Add 3 4 mbp2-2.local. FD00:0000:0000:0000:AEBC:32FF:FEAE:CAEB% 120
0:12:41.025 Add 2 4 mbp2-2.local. 192.168.177.20 120
^C
Summary
Assuming my first command had returned some _airprint
service available in my network, then my guess is that one of the returned lines would read:
00:00:00.000 Add 3 4 . _tcp.local. _airprint
Thus, my second command would have to be:
kp@zdv-wireless-43-219:> dns-sd -B _airprint._tcp local.
I assume this could return something like
200:00:00.000 Add 3 4 local. _airprint._tcp. Some AirPrinter @ somehost
Then my third command should read:
kp@zdv-wireless-43-219:> dns-sd -L "Some AirPrinter @ somehost" local.
Which would return a line telling you "... can be reached at somewhere.local.:1234". From which to derive the fourth command:
kp@zdv-wireless-43-219:> dns-sd -Gv4v6 somewhere.local.
Caveats: The last part, about AirPrint service discovery may be wrong. It could be the case that AirPrint services announce themselves just as standard IPP services do. You have to find out yourself. If you do, please report back.
Update
I've googled a bit for "_airprint._tcp
".
I didn't find a single instance of anybody who reported in some forum their output from dns-sd -B
listing this particular string.
However, there were lots + lots of _airplay._tcp
and _ipp._tcp
results. This means that "_airprint._tcp
" does not seem to exist, and AirPrint printers must be using a different signature to make themselves known to potential clients. However, we already know that all AirPrint services use IPP for communication with their clients, so they also MUST be making the _ipp._tcp
service type announcements.
Hence it is safe to conclude that...
- ...all AirPrint devices will announce themselves as
_ipp._tcp
(not _airprint._tcp
). Also, it looks like...
- ...you can identify AirPrint devices by looking for the
TXT
record of urf="$anything"
and pdl="$anything,image/urf"
.
To verify this, I checked with what the (fake) announcement from dns-sd.org tells about its AirPrint (warning, it is not permanently on the Internet, sometimes it goes away for hours...). It does return this:
kp@zdv-wireless-43-219:> dns-sd -Z _ipp._tcp,_universal dns-sd.org.
Browsing for _ipp._tcp,_universal.dns-sd.org.
DATE: ---Sat 21 May 2016---
1:40:45.688 ...STARTING...
; To direct clients to browse a different domain, substitute that domain in place of '@'
lb._dns-sd._udp PTR @
; In the list of services below, the SRV records will typically reference dot-local Multicast DNS names.
; When transferring this zone file data to your unicast DNS server, you'll need to replace those dot-local
; names with the correct fully-qualified (unicast) domain name of the target host offering the service.
_ipp._tcp PTR Stuart's\032Home\032AirPrint\032Printer._ipp._tcp
Stuart's\032Home\032AirPrint\032Printer._ipp._tcp SRV 0 0 631 airprint.dns-sd.org. ; Replace with unicast FQDN of target host
Stuart's\032Home\032AirPrint\032Printer._ipp._tcp TXT "txtvers=1" "qtotal=1" "rp=ipp/printer" \
"pdl=application/postscript,application/vnd.hp-PCL,application/vnd.hp-PCLXL,application/pdf,image/urf" \
"URF=CP99,W8,OB10,PQ3-4-5,ADOBERGB24,DEVRGB24,DEVW8,SRGB24,IS1-2-4,MT1-2-3-5-12,MT1-2-3-5-12,RS600" \
"ty=HP LaserJet 400 color M451nw" "product=(HP LaserJet 400 color M451nw)" \
"priority=10" "adminurl=http://www.dns-sd.org/ServerStaticSetup.html" \
"note=At Stuart's house" "Color=T" "Duplex=F" "Scan=F"
^C
Indeed, "Stuart's Home AirPrint Printer" mentions "URF" in its TXT records.
So, to summarize the answer to your question "How can I get the IP addresses of all AirPrint printers?"
- First, list all IPP printers.
- Second, exclude these IPP printers which do NOT enumerate the two above mentioned urf-entries in their TXT records.
Verify my statements
The following (minimal) command will announce a fake AirPrint device in your LAN (until you cancel the command with ^C):
dns-sd \
-R "Minimal AirPrint Demo (dummy+fake printer fooling iPad clients)" \
_ipp._tcp.,_universal \
. \
631 \
pdl="image/urf" \
URF=""
Your iOS devices will now enumerate this printer amongst its auto-discovered AirPrint devices.
(BTW, you can announce the port as something different from 631 too -- the iOS clients will still identify it as an AirPrint device...)
Now repeat this little experiment, just leave one of the two image/urf
or URF=""
statements off your command:
- The fake device will still appear as an IPP printer in the DNS-SD/Bonjour browse lists.
- But iOS clients will only list as AirPrint-capable these (fake or real) devices with the "URF"-related entries.
dns-sd -Z
for this reason: every AirPrint-capable printer is also IPP-capable. But not every IPP-capable printer is AirPrint-capable (or has AirPrint disabled). For more details, see my answer.