1ReadMe About mDNSPosix 2---------------------- 3 4mDNSPosix is a port of Apple's Multicast DNS and DNS Service Discovery 5code to Posix platforms. 6 7Multicast DNS and DNS Service Discovery are technologies that allow you 8to register IP-based services and browse the network for those services. 9For more information about mDNS, see the mDNS web site. 10 11 <http://www.multicastdns.org/> 12 13Multicast DNS is part of a family of technologies resulting from the 14efforts of the IETF Zeroconf working group. For information about 15other Zeroconf technologies, see the Zeroconf web site. 16 17 <http://www.zeroconf.org/> 18 19Apple uses the trade mark "Bonjour" to describe our implementation of 20Zeroconf technologies. This sample is designed to show how easy it is 21to make a device "Bonjour compatible". 22 23The "Bonjour" trade mark can also be licensed at no charge for 24inclusion on your own products, packaging, manuals, promotional 25materials, or web site. For details and licensing terms, see 26 27 <http://developer.apple.com/bonjour/> 28 29The code in this sample was compiled and tested on Mac OS X (10.1.x, 3010.2, 10.3), Solaris (SunOS 5.8), Linux (Redhat 2.4.9-21, Fedora Core 1), 31and OpenBSD (2.9). YMMV. 32 33 34Packing List 35------------ 36 37The sample uses the following directories: 38 39o mDNSCore -- A directory containing the core mDNS code. This code 40 is written in pure ANSI C and has proved to be very portable. 41 Every platform needs this core protocol engine code. 42 43o mDNSShared -- A directory containing useful code that's not core to 44 the main protocol engine itself, but nonetheless useful, and used by 45 more than one (but not necessarily all) platforms. 46 47o mDNSPosix -- The files that are specific to Posix platforms: Linux, 48 Solaris, FreeBSD, NetBSD, OpenBSD, etc. This code will also work on 49 OS X, though that's not its primary purpose. 50 51o Clients -- Example client code showing how to use the API to the 52 services provided by the daemon. 53 54 55Building the Code 56----------------- 57 58The sample does not use autoconf technology, primarily because I didn't 59want to delay shipping while I learnt how to use it. Thus the code 60builds using a very simple make file. To build the sample you should 61cd to the mDNSPosix directory and type "make os=myos", e.g. 62 63 make os=panther 64 65For Linux you would change that to: 66 67 make os=linux 68 69There are definitions for each of the platforms I ported to. If you're 70porting to any other platform please add appropriate definitions for it 71and send us the diffs so they can be incorporated into the main 72distribution. 73 74 75Using the Sample 76---------------- 77When you compile, you will get: 78 79o Main products for general-purpose use (e.g. on a desktop computer): 80 - mdnsd 81 - libmdns 82 - nss_mdns (See nss_ReadMe.txt for important information about nss_mdns) 83 84o Standalone products for dedicated devices (printer, network camera, etc.) 85 - mDNSClientPosix 86 - mDNSResponderPosix 87 - mDNSProxyResponderPosix 88 89o Testing and Debugging tools 90 - dns-sd command-line tool (from the "Clients" folder) 91 - mDNSNetMonitor 92 - mDNSIdentify 93 94As root type "make install" to install eight things: 95o mdnsd (usually in /usr/sbin) 96o libmdns (usually in /usr/lib) 97o dns_sd.h (usually in /usr/include) 98o startup scripts (e.g. in /etc/rc.d) 99o manual pages (usually in /usr/share/man) 100o dns-sd tool (usually in /usr/bin) 101o nss_mdns (usually in /lib) 102o nss configuration files (usually in /etc) 103 104The "make install" concludes by executing the startup script 105(usually "/etc/init.d/mdns start") to start the daemon running. 106You shouldn't need to reboot unless you really want to. 107 108Once the daemon is running, you can use the dns-sd test tool 109to exercise all the major functionality of the daemon. Running 110"dns-sd" with no arguments gives a summary of the available options. 111This test tool is also described in detail, with several examples, 112in Chapter 6 of the O'Reilly "Zero Configuration Networking" book. 113 114 115How It Works 116------------ 117 +--------------------+ 118 | Client Application | 119 +----------------+ +--------------------+ 120 | uds_daemon.c | <--- Unix Domain Socket ---> | libmdns | 121 +----------------+ +--------------------+ 122 | mDNSCore | 123 +----------------+ 124 | mDNSPosix.c | 125 +----------------+ 126 127mdnsd is divided into three sections. 128 129o mDNSCore is the main protocol engine 130o mDNSPosix.c provides the glue it needs to run on a Posix OS 131o uds_daemon.c exports a Unix Domain Socket interface to 132 the services provided by mDNSCore 133 134Client applications link with the libmdns, which implements the functions 135defined in the dns_sd.h header file, and implements the IPC protocol 136used to communicate over the Unix Domain Socket interface to the daemon. 137 138Note that, strictly speaking, nss_mdns could be just another client of 139mdnsd, linking with libmdns just like any other client. However, because 140of its central role in the normal operation of multicast DNS, it is built 141and installed along with the other essential system support components. 142 143 144Clients for Embedded Systems 145---------------------------- 146 147For small devices with very constrained resources, with a single address 148space and (typically) no virtual memory, the uds_daemon.c/UDS/libmdns 149layer may be eliminated, and the Client Application may live directly 150on top of mDNSCore: 151 152 +--------------------+ 153 | Client Application | 154 +--------------------+ 155 | mDNSCore | 156 +--------------------+ 157 | mDNSPosix.c | 158 +--------------------+ 159 160Programming to this model is more work, so using the daemon and its 161library is recommended if your platform is capable of that. 162 163The runtime behaviour when using the embedded model is as follows: 164 1651. The application calls mDNS_Init, which in turns calls the platform 166 (mDNSPlatformInit). 167 1682. mDNSPlatformInit gets a list of interfaces (get_ifi_info) and registers 169 each one with the core (mDNS_RegisterInterface). For each interface 170 it also creates a multicast socket (SetupSocket). 171 1723. The application then calls select() repeatedly to handle file descriptor 173 events. Before calling select() each time, the application calls 174 mDNSPosixGetFDSet() to give mDNSPosix.c a chance to add its own file 175 descriptors to the set, and then after select() returns, it calls 176 mDNSPosixProcessFDSet() to give mDNSPosix.c a chance to receive and 177 process any packets that may have arrived. 178 1794. When the core needs to send a UDP packet it calls 180 mDNSPlatformSendUDP. That routines finds the interface that 181 corresponds to the source address requested by the core, and 182 sends the datagram using the UDP socket created for the 183 interface. If the socket is flow send-side controlled it just 184 drops the packet. 185 1865. When SocketDataReady runs it uses a complex routine, 187 "recvfrom_flags", to actually receive the packet. This is required 188 because the core needs information about the packet that is 189 only available via the "recvmsg" call, and that call is complex 190 to implement in a portable way. I got my implementation of 191 "recvfrom_flags" from Stevens' "UNIX Network Programming", but 192 I had to modify it further to work with Linux. 193 194One thing to note is that the Posix platform code is very deliberately 195not multi-threaded. I do everything from a main loop that calls 196"select()". This is good because it avoids all the problems that often 197accompany multi-threaded code. If you decide to use threads in your 198platform, you will have to implement the mDNSPlatformLock() and 199mDNSPlatformUnlock() calls which are currently no-ops in mDNSPosix.c. 200 201 202Once you've built the embedded samples you can test them by first 203running the client, as shown below. 204 205 quinn% build/mDNSClientPosix 206 Hit ^C when you're bored waiting for responses. 207 208By default the client starts a search for AppleShare servers and then 209sits and waits, printing a message when services appear and disappear. 210 211To continue with the test you should start the responder in another 212shell window. 213 214 quinn% build/mDNSResponderPosix -n Foo 215 216This will start the responder and tell it to advertise a AppleShare 217service "Foo". In the client window you will see the client print out 218the following as the service shows up on the network. 219 220 quinn% build/mDNSClientPosix 221 Hit ^C when you're bored waiting for responses. 222 *** Found name = 'Foo', type = '_afpovertcp._tcp.', domain = 'local.' 223 224Back in the responder window you can quit the responder cleanly using 225SIGINT (typically ^C). 226 227 quinn% build/mDNSResponderPosix -n Foo 228 ^C 229 quinn% 230 231As the responder quits it will multicast that the "Foo" service is 232disappearing and the client will see that notification and print a 233message to that effect (shown below). Finally, when you're done with 234the client you can use SIGINT to quit it. 235 236 quinn% build/mDNSClientPosix 237 Hit ^C when you're bored waiting for responses. 238 *** Found name = 'Foo', type = '_afpovertcp._tcp.', domain = 'local.' 239 *** Lost name = 'Foo', type = '_afpovertcp._tcp.', domain = 'local.' 240 ^C 241 quinn% 242 243If things don't work, try starting each program in verbose mode (using 244the "-v 1" option, or very verbose mode with "-v 2") to see if there's 245an obvious cause. 246 247That's it for the core functionality. Each program supports a variety 248of other options. For example, you can advertise and browse for a 249different service type using the "-t type" option. Use the "-?" option 250on each program for more user-level information. 251 252 253Caveats 254------- 255Currently the program uses a simple make file. 256 257The Multicast DNS protocol can also operate locally over the loopback 258interface, but this exposed some problems with the underlying network 259stack in early versions of Mac OS X and may expose problems with other 260network stacks too. 261 262o On Mac OS X 10.1.x the code failed to start on the loopback interface 263 because the IP_ADD_MEMBERSHIP option returns ENOBUFS. 264 265o On Mac OS X 10.2 the loopback-only case failed because 266 "sendto" calls fails with error EHOSTUNREACH. (3016042) 267 268Consequently, the code will attempt service discovery on the loopback 269interface only if no other interfaces are available. 270 271I haven't been able to test the loopback-only case on other platforms 272because I don't have access to the physical machine. 273 274 275Licencing 276--------- 277This source code is Open Source; for details see the "LICENSE" file. 278 279Credits and Version History 280--------------------------- 281If you find any problems with this sample, mail <dts@apple.com> and I 282will try to fix them up. 283 2841.0a1 (Jul 2002) was a prerelease version that was distributed 285internally at Apple. 286 2871.0a2 (Jul 2002) was a prerelease version that was distributed 288internally at Apple. 289 2901.0a3 (Aug 2002) was the first shipping version. The core mDNS code is 291the code from Mac OS 10.2 (Jaguar) GM. 292 293Share and Enjoy 294 295Apple Developer Technical Support 296Networking, Communications, Hardware 297 2986 Aug 2002 299 300Impact: A local network user may cause a denial of the Bonjour service 301Description: An error handling issue exists in the Bonjour Namespace 302Provider. A local network user may send a maliciously crafted multicast 303DNS packet leading to an unexpected termination of the Bonjour service. 304This update addresses the issue by performing additional validation of 305multicast DNS packets. This issue does not affect systems running Mac OS 306X or Windows. 307CVE-ID 308CVE-2011-0220 : JaeSeung Song of the Department of Computing at Imperial 309College London 310 311To Do List 312---------- 313• port to a System V that's not Solaris 314• use sig_atomic_t for signal to main thread flags 315