Table of contents
LLMNR, Multicast DNS and names on your LAN
Let's say you've got a LAN at home (crazy thought!). You're a single minded kind of person, so all your computers are running the same operating system family. Assuming you remember what you named them, you can open a terminal and run "ping BobPC" and get back some ping timings. All is well.
Now you have a friend over, who's running one of Those Other operating systems. "Very well," you say, "something as basic as naming devices on a LAN must surely be solved in an interoperable manner by now, it's 2015 after all." And you'd be wrong, of course, which you find out when you ask your friend what the name of the visiting computer is and try typing "ping AliceMac" without getting any replies back.
Name resolution and service discovery
When you're looking for something, you're usually looking for either a specific object, or any object that will enable you to complete your current task. If you want to talk to Bob, you really need to find Bob. If you're in need of a printer, it's likely that just about any printer will do.
These two different types of search are called "name resolution" and "service discovery" in the context of computers and LANs. A name resolution will tell you the address of a specific device, and service discovery will give you a list of devices that provide a requested service.
A short history of resolutions
A long time ago, there was a protocol called NetBIOS. A surprisingly long time ago, actually: it was created in the early 80s . This also explains some of the limitations that we've learned to live with, like the limited name length allowed and such. Microsoft first implemented the protocol in 1985, and we've had it all the way up to Windows 2000. NetBIOS was used not only for name resolution, but also for network printing and file sharing.
In other parts of the world, other protocols were used. Macs used AppleTalk, that did the same things. I don't know what the UNIX way of solving this problem in the good ol'days was (if there even was a way?); when Linux computers started getting common they mostly did what Microsoft did and implemented the NetBIOS protocol family - probably using Samba.
Then the future started happening. MacOS Classic was replaced with OSX, and AppleTalk was considered old and in need of replacement. The printing functionality was replaced by CUPS, and service discovery and name resolution was replaced by Multicast DNS (mDNS). In the Linux world, avahi (which implements mDNS) started appearing alongside Samba.
On the Windows side, Microsoft decided that NetBIOS wouldn't do any longer, and replaced it with, among other protocols, LLMNR (Link-Local Multicast Name Resolution).
How name resolution on a LAN works
- Someone looking for something shouts "does anyone know where Foo is?"
- If there is a Foo, it responds with "I'm here"
A slight aside
mDNS and LLMNR both do name resolution, but mDNS is also used for service discovery when paired with something called DNS-SD (DNS Service Discovery) . On the LLMNR side, service discovery is handled using a protocol called SSDP (Simple Service Discovery Protocol) which is based on HTTP-over-UDP. Yes, really.
Both LLMNR and mDNS are based on the same general principle: use a subset of DNS and send requests over multicast. Multicast is a variant of broadcast where packets are delivered to anyone who has notified the switches (and possibly routers) on the network that they'd like to get them. This means that when someone is trying to resolve a name, all interested devices on the network will see the request.
In the case of mDNS, replies are also sent over multicast so that everyone can see them and keep their local mDNS cache up to date. LLMNR replies are sent using unicast, so only the device that sent the request will see the reply. For both protocols, if no reply is received within a few hundred milliseconds, the request is repeated a few times. Eventually the requester will give up and the resolution fails.
While LLMNR and mDNS are superficially very similar, when looking at the details it turns out that there are some significant differences. The differences are big enough that the protocols aren't compatible, and also big enough that one of the protocols is being turned into an Internet Standard while the other was turned down by the IETF.
The IETF debacle
Work on the LLMNR protocol went on in a IETF workgroup, and when they decided that they were more or less done they sent out a "Last Call" to the rest of the IETF. The purpose of the last call to a "global" mailing list is to get some final feedback, by having IETF members who aren't part of the originating workgroup and haven't followed the work on the document read and opine. And this time, they did have opinions. Lots of them. And most of the feedback was of the type "ehm, this really isn't a good idea". I tried finding a link to the actual Last Call email, but the closest I've managed to find is a reply by the author of mDNS . Do read a couple of emails in that thread, it's interesting!
Now, if I had spent a couple of years working on something and gotten the same reaction when I presented the result, I'm pretty sure that I'd be a bit defensive too. I haven't read all the emails in the list archive, there are a lot of them, but I did read quite a few in a "reality TV drama" kind of fascination.
Some major objections brought up were (according to a summary email ):
- Confusion with mDNS (which was already widely in use at this point)
- Security concerns: adversaries may be able to spoof DNS replies
- No boundary between normal DNS and LLMNR
In the end, the IETF decided that LLMNR wasn't going to achieve consensus and put it up as an Informational RFC. mDNS was worked on some more, and in 2013 it was promoted to Proposed Standard. Microsoft didn't care and continues to use LLMNR anyway [but see the update note at the end !].
I found the security objections to LLMNR interesting. In short, since the LLMNR namespace overlaps "normal" DNS namespace, it's possible for a device on the local network to impersonate any domain normally located on the Internet. LLMNR lookups are done after trying and failing with normal DNS, which means that a lookup of "mybank.com" will usually be located in DNS before reaching LLMNR. However, suppose that I'd like to trick you into connecting to my device instead of the bank's server. I would be able to do that by causing a DoS of normal DNS services (by various means), and then responding with my device's address when your computer performs a lookup of "mybank.com" over LLMNR. This is especially easy in the case of "coffee shop" wireless networks, where you connect to untrusted networks.
mDNS solves this problem by allocating a specific subset of the DNS namespace for use exclusively with mDNS: any lookup of a name ending in ".local" will use only mDNS, and all other queries will use normal DNS.
LLMNR proponents claim that this can be solved by protecting the DNS records using DNSSEC, but it's unclear to me how the DNSSEC information can be a factor when the adversary has cut off access to the normal DNS server.
Getting back on track
Now, we started out by having computers on our network that don't talk the same language when trying to discover each other. We now know that there are two competing protocols in use, and that Windows uses one of them while everyone else uses the other. How do we bridge this gap?
The obvious solution might be to look at how many computers you've got of each kind, and then install software that implements the missing protocol on the kind you've got least of. So if you've got ten Macs and a single Windows box, install mDNS on the Windows machine.
I don't know of any LLMNR implementations for OSX, but there is one for Linux . I haven't tried it, but I assume it works as advertised. If Windows is your minority, you can install Bonjour print services which includes mDNS.
Or you can do what I did, and get coding!
LLMNR <> mDNS proxy
In case you're not interested in installing software on every machine that comes into your network and doesn't run the dominant protocol, there's an alternate solution: install and run a proxy software on some machine that's on all the time (a server or such), that will listen for unanswered requests on each protocol and try to resolve them using the alternate protocol. By doing this you can make sure that all requests for "somebox.local" will be resolved, regardless of which OS the computer is running. This is due to a small detail in the way Windows handles lookups of names ending in ".local"; if the lookup fails it will be tried again but with the ".local" suffix removed.
This means that a Mac will query for "somebox.local" using mDNS, which can be proxied by a LLMNR query for "somebox", and a Windows box will do a LLMNR query for "somebox" which can be proxied by a mDNS query for "somebox.local".
To try this hypothesis, I whipped up a simple Python script that listens for LLMNR queries, and if nobody has answered within 100ms or so does a mDNS lookup to try to find the answer. If something is found, a LLMNR reply is sent. So now the Windows machines on the LAN at work can finally resolve the URLs to "intranet.local" I send in emails. No more having to remember that 192.168.0.20 is the file server and 192.168.0.21 is the intranet server - it's almost like we're living in the future! I can also run services on DHCP-configured servers (don't ask…), and things will continue working after reboots of the DHCP server.
Windows 10 will support mDNS and DNS-SD!
According to a comment on Hacker News Windows 10 will support mDNS and DNS-SD. That sounds awesome, but finding details about this wasn't easy. The best I could find from a few quick searches was a note in the hardware developer section of MSDN that says that Windows 10 will indeed locate printers using mDNS+DNS-SD .