I am trying to make a list of all AirPrint printers on the network at a school. We have many of them because of all the classroom and office printers, but they have not been set up with meaningful names. I tried reading the DHCP allocation table in the router, but many of the printers do not report a host name. I can't check printers in-person because of the disruption to classes from going in to every room and playing with the 1-3 printers there.
The dns-sd
command as in How to find IP address of my other Mac?
gives a column called Instance Name, rather than the host name. Using the dns-sd -G
option on the instance names gave no such record.
dns-sd -Z
is closer, since it gives host names to look up with the G
option, but it doesn't give a complete list. There are many more printers in the Add Printer dialog on a Mac than there are in the output of dns-sd -Z
.
Does anyone have some code or script to just find all the IP addresses of things advertising by Bonjour?
Best Answer
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):
So yes, there is indeed an IPP print service (but no AirPrint one, which
would be marked bystand out being tagged as Service Type of_airprint._tcp
in the list).Second, browse for all present services of type "IPP":
Ok, one of the instance names is "Officejet 6600 @ mbp".
Third, lookup specific info about the printer named "Officejet 6600 @ mbp":
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:
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:Thus, my second command would have to be:
I assume this could return something like
Then my third command should read:
Which would return a line telling you "... can be reached at somewhere.local.:1234". From which to derive the fourth command:
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...
_ipp._tcp
(not_airprint._tcp
). Also, it looks like...TXT
record ofurf="$anything"
andpdl="$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:
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?"
Verify my statements
The following (minimal) command will announce a fake AirPrint device in your LAN (until you cancel the command with ^C):
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
orURF=""
statements off your command: