At the Hadrian Hotel

At the Hadrian Hotel

Sunday, February 17, 2008

Bonjour Printing to a Linux CUPS Server

Bonjour (aka ZeroConf - mostly) printing looks like a great way to print from a Mac to a Bonjour-capable printer on the same IP subnet. However, on a network where the printers are not on the same subnet as the hosts that want to use them, something else needs to be done.

In our case, we use a Linux box running CUPS with the cups-lpd listener. All of the printers are on their own private subnet that can only be accessed form within the Computer Science department. All printing is intended to go through the CUPS server, which very nicely takes care of format conversions as needed. This architecture also gives us the ability to do print job accounting and to move jobs to other printers should one fail with jobs in the queue.

The problem is that anybody with a Mac or PC that wants to print something needs to add a network printer definition to their machine. Thanks to the Bonjour capabilities of the Mac, we have been able to use static DNS entries to define and advertise all of our print queues to any Mac user. Here's what we did....

For our printer advertisements we are using statically defined entries in our DNS files to enable DNS Service Discovery (DNS-SD) without the need for the Multicast DNS used by Bonjour-enabled printers to advertise themselves. We start with some boilerplate resource records in our main zone file:

;; Service Browsing
b._dns-sd._udp PTR @
lb._dns-sd._udp PTR @

;; Available Services
_services._dns-sd._udp PTR _ipp._tcp
_services._dns-sd._udp PTR _printer._tcp

While we only use LPD for printing (the '_printer' record above), I've included the '_ipp' record for those who prefer a more more printing protocol.

The next thing to do is define the print queues themselves, making sure to specify the various DNS records required by Bonjour printing support. Most of the information was found in the Apple Bonjour Printing Specification, but there were a few bits here and there that I put together from various searches around the 'net. I also used a bit of tcpdump sleuthing to discover what actual Macs and printers announce when advertising Bonjour printers. With all that said, here is an example print queue entry:

_printer._tcp PTR hp_218._printer._tcp
hp_218._printer._tcp SRV 0 0 515 lpdrelay.example.edu.
TXT "txtvers=1" \
"qtotl=1" \
"rp=hp_218" \
"ty=HP LaserJet 4000 Series PS" \
"product=(HP LaserJet 4000 Series)" \
"transparent=t" \
"copies=t" \
"duplex=t" \
"color=f" \
"pdl=application/pdf,application/postscript"

Please note that the "\"-escaped newlines are only included for readability. One key insight I picked up from a mailing list post was that the TXT record fields all needed to be on a single line (at least for the version of BIND I'm running). The Bonjour printing specification allows for only a single TXT record, but requires multiple attributes.

The txtvers, qtotl, transparent, copies and pdl attributes are the same for all of our printers. The rp attribute specifies the name of the print queue on the CUPS server. The ty attribute provides a "display name" for the user's printer browser and product needs to be the same value as the Product specification in the printer's PPD file. I suspect that the values for color and duplex are fairly obvious. :-)

In our DNS configuration file, we have a definition similar to the one above for every printer that our CUPS server is driving, and while we are currently using the LPD protocol, we could just as just as easily use IPP for printing. For IPP, the above example would require 2 simple changes: All instances of _printer would be replaced with _ipp and the 515 port number in the SRV record would be changed to 631. Both configurations have been tested and appear to work just fine.

If you have any interest in reading further, I have saved a number of bookmarks concerning Bonjour and DNS-SD in del.icio.us.

3 comments:

Doug C said...

Great article...I got as far as being able to see my advertised printer in the Bonjour browser, but I am unable to print. I get "Can't resolve link-local name". I'm using an IPP print server because I didn't want to mess with the TXT entries.

Chris Tengi said...

Doug,

Thanks for the compliment....

My guess here is that the DNS names for your print queues are not using your domain, but are defaulting to ".local" instead. Make sure that the zone file containing your print queue definitions has the proper $ORIGIN statement.

We do this on our primary department DNS servers, with the print queue information in the same zone file as all of our A, CNAME, MX, HINFO, LOC and RP records.

Also, using IPP may or may not remove the need for the TXT records. My understanding is that Bonjour thinks it is talking to a printer and not a print server. It may require TXT record hints regardless of the underlying printing protocol.

Doug C said...

I was able to get it printing the other day. It turns out you don't need any sort of DNS entry for the printer, what I was missing was defining

myprinter._printer._tcp

again before the TXT entry. So now LPD printing works great and I'm working on IPP. When trying to print to IPP I'm getting the error:

Unable to get printer status (client-error-forbidden)!

I've tried a few permutations of "rp=printer_queue" ie "rp=ipp/printer_queue". The print server is Mac OS Tiger.