One of the reasons I bought a Mac for myself and my wife is that I could never get printer sharing working between Linux and Windows. I figured if Marina and I both had Macs then the problem would be solved. Unfortunately, I was wrong. While Apple has mostly embraced Bonjour technology there is still one major area that is left out – Apple's Printer Server (e.g. the open source CUPS) which uses its own multicast based discovery solution. When I hooked my USB printer to my OS X box and turned on printer sharing I couldn't get my wife's Mac to see the printer! The problem turned out to be that both my wife and I's computers have unique IP addresses that we get from our ISP's DHCP server. Unfortunately the ISP's DHCP server gave us addresses in different subnets! CUPS default configuration does not allow printer sharing between machines that are not on the same subnet. The CUPS configuration can be overridden fairly trivially but I don't want to because it would either mean hard coding in my wife's IP address (which changes) or allowing the whole world to print on my printer (which I'd rather not). Thankfully there was a really trivial solution to the problem that was pointed out to me by Stuart Cheshire, the father of Bonjour.
Stuart actually suggested two solutions. I selected his second solution and describe in detail how to implement it below. At the end of this article I explain what his first solution was and why I didn't choose it.
The crux of Stuart's solution is to create a second Ethernet configuration on both my wife and I's machines. This is trivial to set up (once you know how) and from there everything will just 'work', e.g. the printers will just show up.
Instructions for the machine that is hosting the printer:
Step 1 – Go to system preferences (you can get there by clicking on the apple in the upper left hand corner of the screen)
Step 2 – Go to 'Sharing'
Step 3 – Select 'Services'
Step 4 – Select 'Printer Sharing' (depending on how you configured your machine you might have to click on the lock icon at the bottom left hand corner of the dialog box and type in your administrator password before being able to change the Printer Sharing setting)
Step 5 – 'Show All'
Step 6 – 'Network'
Step 7 – 'Show – Network Port Configurations' (this is a choice in the drop down titled 'Show')
Step 8 – Select 'Built-in Ethernet'
Step 9 – Press 'duplicate'
Step 10 – Enter in a title, I choose 'Local Only Ethernet'
Step 11 – Press 'Apply Now'
Step 12 – Select 'Show – 'Local Only Ethernet''
Step 13 – Set 'Configure IPv4' to 'Manually'
Step 14 – Set 'IP Address' to '10.0.0.1'
Step 15 – Press 'Apply Now'
The computer hosting the printer is now ready to share that printer with all local machines (including one's your ISP has given the same subnet address to, so beware!).
For each of the machines that you want to be able to use the printer with do the following:
Step 1 – System Preferences
Step 2 – Step 11: Follow the instructions specified above for steps 6-15 with the exception that in step 14 when entering the IP address enter 10.0.0.2. If you are adding multiple machines then each one needs its own IP address, just increment, e.g. 10.0.0.3, 10.0.0.4, etc.
Step 12 – 'Show All'
Step 13 – 'Print & Fax'
Step 14 – Press the '+' Button
Step 15 – The printer on the other machine should show up in the list of available printers, select it
Step 16 – Press 'add'
That's it. The whole process should take about two minutes.
What the previous does is create a second Ethernet interface on both machines that use an IP address from the reserved 10.X.X.X range. This is what is known as a 'private address space', that is, IP addresses in the 10.X.X.X range are marked as being 'private' and with a few exceptions I won't get into here are not to be routed so this means that machines that are not physically attached to my local network can't use this address at all. The next trick is that Apple's default subnet mask for manually entered addresses is 255.255.255.0 which means that all addresses in the 10.0.0.X range are automatically on the same subnet. So the end result is that both machines now have alternate locally routed only addresses that are on the same subnet. So, voila, CUPS work.
The previous describes Stuart's second solution, his first solution was to change the CUPS configuration to allow connections from computers that aren't on the same sub-domain. Then I would go to my wife's machine and manually create a printer queue that used my machines ".local" DNS address. The ".local" domain triggers the use of multicast DNS resolution. In other words when a computer looks for a DNS name like "foo.local" it will try to find the computer that owns that name by essentially 'yelling' out to all the local machines "hey, anyone go by the name foo?". While my wife and I's machines are on two separate subnets they are still physically connected by the same Ethernet switch and so can see each other's multicast packets. All OS X boxes give themselves ".local" names (go to System Preferences – Sharing – you should see text at the top that says "Other computers on your local subnet can access your computer at X.local") so by giving the Printer Queue my machine's .local name as its address my wife's machine would always be able to find my machine and it's attached printer even when my IP address is changed by DHCP.
I didn't like this suggestion for two reasons. First, I didn't like the idea of opening up my CUPS configuration, that sounded like a security hole since anyone that knew my IP address could now print on my machine. Although, if memory serves, it is possible to configure CUPS to provide access to specific DNS addresses so I could just have listed my wife's ".local" DNS address. Second, I like things to work automatically and having all these configurations in CUPS and in my wife's machine made me nervous. I wanted something simpler. Which is why I choose Stuart's second suggestion.