/* -*- Mode: C; tab-width: 4 -*-
 *
 * Copyright (c) 2002-2004 Apple Computer, Inc. All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *     http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * Formatting notes:
 * This code follows the "Whitesmiths style" C indentation rules. Plenty of discussion
 * on C indentation can be found on the web, such as <http://www.kafejo.com/komp/1tbs.htm>,
 * but for the sake of brevity here I will say just this: Curly braces are not syntactially
 * part of an "if" statement; they are the beginning and ending markers of a compound statement;
 * therefore common sense dictates that if they are part of a compound statement then they
 * should be indented to the same level as everything else in that compound statement.
 * Indenting curly braces at the same level as the "if" implies that curly braces are
 * part of the "if", which is false. (This is as misleading as people who write "char* x,y;"
 * thinking that variables x and y are both of type "char*" -- and anyone who doesn't
 * understand why variable y is not of type "char*" just proves the point that poor code
 * layout leads people to unfortunate misunderstandings about how the C language really works.)
 */

#include "mDNSEmbeddedAPI.h"           // Defines the interface provided to the client layer above
#include "DNSCommon.h"
#include "mDNSPosix.h"				 // Defines the specific types needed to run mDNS on this platform
#include "dns_sd.h"

#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
#ifndef __ANDROID__
  #include <syslog.h>
#endif
#include <stdarg.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/time.h>
#include <sys/socket.h>
#include <sys/uio.h>
#include <sys/select.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <time.h>                   // platform support for UTC time

#if USES_NETLINK
#include <asm/types.h>
#include <linux/netlink.h>
#include <linux/rtnetlink.h>
#else // USES_NETLINK
#include <net/route.h>
#include <net/if.h>
#endif // USES_NETLINK

#include "mDNSUNP.h"
#include "GenLinkedList.h"

// ***************************************************************************
// Structures

// We keep a list of client-supplied event sources in PosixEventSource records 
struct PosixEventSource
	{
	mDNSPosixEventCallback		Callback;
	void						*Context;
	int							fd;
	struct  PosixEventSource	*Next;
	};
typedef struct PosixEventSource	PosixEventSource;

// Context record for interface change callback
struct IfChangeRec
	{
	int	NotifySD;
	mDNS *mDNS;
	};
typedef struct IfChangeRec	IfChangeRec;

// Note that static data is initialized to zero in (modern) C.
static fd_set			gEventFDs;
static int				gMaxFD;					// largest fd in gEventFDs
static GenLinkedList	gEventSources;			// linked list of PosixEventSource's
static sigset_t			gEventSignalSet;		// Signals which event loop listens for
static sigset_t			gEventSignals;			// Signals which were received while inside loop

// ***************************************************************************
// Globals (for debugging)

static int num_registered_interfaces = 0;
static int num_pkts_accepted = 0;
static int num_pkts_rejected = 0;

// ***************************************************************************
// Functions

int gMDNSPlatformPosixVerboseLevel = 0;

#define PosixErrorToStatus(errNum) ((errNum) == 0 ? mStatus_NoError : mStatus_UnknownErr)

mDNSlocal void SockAddrTomDNSAddr(const struct sockaddr *const sa, mDNSAddr *ipAddr, mDNSIPPort *ipPort)
	{
	switch (sa->sa_family)
		{
		case AF_INET:
			{
			struct sockaddr_in *sin          = (struct sockaddr_in*)sa;
			ipAddr->type                     = mDNSAddrType_IPv4;
			ipAddr->ip.v4.NotAnInteger       = sin->sin_addr.s_addr;
			if (ipPort) ipPort->NotAnInteger = sin->sin_port;
			break;
			}

#if HAVE_IPV6
		case AF_INET6:
			{
			struct sockaddr_in6 *sin6        = (struct sockaddr_in6*)sa;
#ifndef NOT_HAVE_SA_LEN
			assert(sin6->sin6_len == sizeof(*sin6));
#endif
			ipAddr->type                     = mDNSAddrType_IPv6;
			ipAddr->ip.v6                    = *(mDNSv6Addr*)&sin6->sin6_addr;
			if (ipPort) ipPort->NotAnInteger = sin6->sin6_port;
			break;
			}
#endif

		default:
			verbosedebugf("SockAddrTomDNSAddr: Uknown address family %d\n", sa->sa_family);
			ipAddr->type = mDNSAddrType_None;
			if (ipPort) ipPort->NotAnInteger = 0;
			break;
		}
	}

#if COMPILER_LIKES_PRAGMA_MARK
#pragma mark ***** Send and Receive
#endif

// mDNS core calls this routine when it needs to send a packet.
mDNSexport mStatus mDNSPlatformSendUDP(const mDNS *const m, const void *const msg, const mDNSu8 *const end,
	mDNSInterfaceID InterfaceID, UDPSocket *src, const mDNSAddr *dst, mDNSIPPort dstPort)
	{
	int                     err = 0;
	struct sockaddr_storage to;
	PosixNetworkInterface * thisIntf = (PosixNetworkInterface *)(InterfaceID);
	int sendingsocket = -1;

	(void)src;	// Will need to use this parameter once we implement mDNSPlatformUDPSocket/mDNSPlatformUDPClose

	assert(m != NULL);
	assert(msg != NULL);
	assert(end != NULL);
	assert((((char *) end) - ((char *) msg)) > 0);

	if (dstPort.NotAnInteger == 0) 
		{
		LogMsg("mDNSPlatformSendUDP: Invalid argument -dstPort is set to 0");
		return PosixErrorToStatus(EINVAL);
		}
	if (dst->type == mDNSAddrType_IPv4)
		{
		struct sockaddr_in *sin = (struct sockaddr_in*)&to;
#ifndef NOT_HAVE_SA_LEN
		sin->sin_len            = sizeof(*sin);
#endif
		sin->sin_family         = AF_INET;
		sin->sin_port           = dstPort.NotAnInteger;
		sin->sin_addr.s_addr    = dst->ip.v4.NotAnInteger;
		sendingsocket           = thisIntf ? thisIntf->multicastSocket4 : m->p->unicastSocket4;
		}

#if HAVE_IPV6
	else if (dst->type == mDNSAddrType_IPv6)
		{
		struct sockaddr_in6 *sin6 = (struct sockaddr_in6*)&to;
		mDNSPlatformMemZero(sin6, sizeof(*sin6));
#ifndef NOT_HAVE_SA_LEN
		sin6->sin6_len            = sizeof(*sin6);
#endif
		sin6->sin6_family         = AF_INET6;
		sin6->sin6_port           = dstPort.NotAnInteger;
		sin6->sin6_addr           = *(struct in6_addr*)&dst->ip.v6;
		sendingsocket             = thisIntf ? thisIntf->multicastSocket6 : m->p->unicastSocket6;
		}
#endif

	if (sendingsocket >= 0)
		err = sendto(sendingsocket, msg, (char*)end - (char*)msg, 0, (struct sockaddr *)&to, GET_SA_LEN(to));

	if      (err > 0) err = 0;
	else if (err < 0)
		{
		static int MessageCount = 0;
        // Don't report EHOSTDOWN (i.e. ARP failure), ENETDOWN, or no route to host for unicast destinations
		if (!mDNSAddressIsAllDNSLinkGroup(dst))
			if (errno == EHOSTDOWN || errno == ENETDOWN || errno == EHOSTUNREACH || errno == ENETUNREACH) return(mStatus_TransientErr);

		if (MessageCount < 1000)
			{
			MessageCount++;
			if (thisIntf)
				LogMsg("mDNSPlatformSendUDP got error %d (%s) sending packet to %#a on interface %#a/%s/%d",
							  errno, strerror(errno), dst, &thisIntf->coreIntf.ip, thisIntf->intfName, thisIntf->index);
			else
				LogMsg("mDNSPlatformSendUDP got error %d (%s) sending packet to %#a", errno, strerror(errno), dst);
			}
		}

	return PosixErrorToStatus(err);
	}

// This routine is called when the main loop detects that data is available on a socket.
mDNSlocal void SocketDataReady(mDNS *const m, PosixNetworkInterface *intf, int skt)
	{
	mDNSAddr   senderAddr, destAddr;
	mDNSIPPort senderPort;
	ssize_t                 packetLen;
	DNSMessage              packet;
	struct my_in_pktinfo    packetInfo;
	struct sockaddr_storage from;
	socklen_t               fromLen;
	int                     flags;
	mDNSu8					ttl;
	mDNSBool                reject;
	const mDNSInterfaceID InterfaceID = intf ? intf->coreIntf.InterfaceID : NULL;

	assert(m    != NULL);
	assert(skt  >= 0);

	fromLen = sizeof(from);
	flags   = 0;
	packetLen = recvfrom_flags(skt, &packet, sizeof(packet), &flags, (struct sockaddr *) &from, &fromLen, &packetInfo, &ttl);

	if (packetLen >= 0)
		{
		SockAddrTomDNSAddr((struct sockaddr*)&from, &senderAddr, &senderPort);
		SockAddrTomDNSAddr((struct sockaddr*)&packetInfo.ipi_addr, &destAddr, NULL);

		// If we have broken IP_RECVDSTADDR functionality (so far
		// I've only seen this on OpenBSD) then apply a hack to
		// convince mDNS Core that this isn't a spoof packet.
		// Basically what we do is check to see whether the
		// packet arrived as a multicast and, if so, set its
		// destAddr to the mDNS address.
		//
		// I must admit that I could just be doing something
		// wrong on OpenBSD and hence triggering this problem
		// but I'm at a loss as to how.
		//
		// If this platform doesn't have IP_PKTINFO or IP_RECVDSTADDR, then we have
		// no way to tell the destination address or interface this packet arrived on,
		// so all we can do is just assume it's a multicast

		#if HAVE_BROKEN_RECVDSTADDR || (!defined(IP_PKTINFO) && !defined(IP_RECVDSTADDR))
			if ((destAddr.NotAnInteger == 0) && (flags & MSG_MCAST))
				{
				destAddr.type = senderAddr.type;
				if      (senderAddr.type == mDNSAddrType_IPv4) destAddr.ip.v4 = AllDNSLinkGroup_v4.ip.v4;
				else if (senderAddr.type == mDNSAddrType_IPv6) destAddr.ip.v6 = AllDNSLinkGroup_v6.ip.v6;
				}
		#endif

		// We only accept the packet if the interface on which it came
		// in matches the interface associated with this socket.
		// We do this match by name or by index, depending on which
		// information is available.  recvfrom_flags sets the name
		// to "" if the name isn't available, or the index to -1
		// if the index is available.  This accomodates the various
		// different capabilities of our target platforms.

		reject = mDNSfalse;
		if (!intf)
			{
			// Ignore multicasts accidentally delivered to our unicast receiving socket
			if (mDNSAddrIsDNSMulticast(&destAddr)) packetLen = -1;
			}
		else
			{
			if      (packetInfo.ipi_ifname[0] != 0) reject = (strcmp(packetInfo.ipi_ifname, intf->intfName) != 0);
			else if (packetInfo.ipi_ifindex != -1)  reject = (packetInfo.ipi_ifindex != intf->index);
	
			if (reject)
				{
				verbosedebugf("SocketDataReady ignored a packet from %#a to %#a on interface %s/%d expecting %#a/%s/%d/%d",
					&senderAddr, &destAddr, packetInfo.ipi_ifname, packetInfo.ipi_ifindex,
					&intf->coreIntf.ip, intf->intfName, intf->index, skt);
				packetLen = -1;
				num_pkts_rejected++;
				if (num_pkts_rejected > (num_pkts_accepted + 1) * (num_registered_interfaces + 1) * 2)
					{
					fprintf(stderr,
						"*** WARNING: Received %d packets; Accepted %d packets; Rejected %d packets because of interface mismatch\n",
						num_pkts_accepted + num_pkts_rejected, num_pkts_accepted, num_pkts_rejected);
					num_pkts_accepted = 0;
					num_pkts_rejected = 0;
					}
				}
			else
				{
				verbosedebugf("SocketDataReady got a packet from %#a to %#a on interface %#a/%s/%d/%d",
					&senderAddr, &destAddr, &intf->coreIntf.ip, intf->intfName, intf->index, skt);
				num_pkts_accepted++;
				}
			}
		}

	if (packetLen >= 0)
		mDNSCoreReceive(m, &packet, (mDNSu8 *)&packet + packetLen,
			&senderAddr, senderPort, &destAddr, MulticastDNSPort, InterfaceID);
	}

mDNSexport TCPSocket *mDNSPlatformTCPSocket(mDNS * const m, TCPSocketFlags flags, mDNSIPPort * port)
	{
	(void)m;			// Unused
	(void)flags;		// Unused
	(void)port;			// Unused
	return NULL;
	}

mDNSexport TCPSocket *mDNSPlatformTCPAccept(TCPSocketFlags flags, int sd)
	{
	(void)flags;		// Unused
	(void)sd;			// Unused
	return NULL;
	}

mDNSexport int mDNSPlatformTCPGetFD(TCPSocket *sock)
	{
	(void)sock;			// Unused
	return -1;
	}

mDNSexport mStatus mDNSPlatformTCPConnect(TCPSocket *sock, const mDNSAddr *dst, mDNSOpaque16 dstport, domainname *hostname, mDNSInterfaceID InterfaceID,
										  TCPConnectionCallback callback, void *context)
	{
	(void)sock;			// Unused
	(void)dst;			// Unused
	(void)dstport;		// Unused
	(void)hostname;     // Unused
	(void)InterfaceID;	// Unused
	(void)callback;		// Unused
	(void)context;		// Unused
	return(mStatus_UnsupportedErr);
	}

mDNSexport void mDNSPlatformTCPCloseConnection(TCPSocket *sock)
	{
	(void)sock;			// Unused
	}

mDNSexport long mDNSPlatformReadTCP(TCPSocket *sock, void *buf, unsigned long buflen, mDNSBool * closed)
	{
	(void)sock;			// Unused
	(void)buf;			// Unused
	(void)buflen;		// Unused
	(void)closed;		// Unused
	return 0;			
	}

mDNSexport long mDNSPlatformWriteTCP(TCPSocket *sock, const char *msg, unsigned long len)
	{
	(void)sock;			// Unused
	(void)msg;			// Unused
	(void)len;			// Unused
	return 0;
	}

mDNSexport UDPSocket *mDNSPlatformUDPSocket(mDNS * const m, mDNSIPPort port)
	{
	(void)m;			// Unused
	(void)port;			// Unused
	return NULL;
	}

mDNSexport void           mDNSPlatformUDPClose(UDPSocket *sock)
	{
	(void)sock;			// Unused
	}
	
mDNSexport void mDNSPlatformUpdateProxyList(mDNS *const m, const mDNSInterfaceID InterfaceID)
	{
	(void)m;			// Unused
	(void)InterfaceID;			// Unused
	}

mDNSexport void mDNSPlatformSendRawPacket(const void *const msg, const mDNSu8 *const end, mDNSInterfaceID InterfaceID)
	{
	(void)msg;			// Unused
	(void)end;			// Unused
	(void)InterfaceID;			// Unused
	}
	
mDNSexport void mDNSPlatformSetLocalAddressCacheEntry(mDNS *const m, const mDNSAddr *const tpa, const mDNSEthAddr *const tha, mDNSInterfaceID InterfaceID)
	{
	(void)m;			// Unused
	(void)tpa;			// Unused
	(void)tha;			// Unused
	(void)InterfaceID;			// Unused
	}	

mDNSexport mStatus mDNSPlatformTLSSetupCerts(void)
	{
	return(mStatus_UnsupportedErr);
	}
	
mDNSexport void mDNSPlatformTLSTearDownCerts(void)
	{
	}

mDNSexport void mDNSPlatformSetAllowSleep(mDNS *const m, mDNSBool allowSleep, const char *reason)
	{
	(void) m;
	(void) allowSleep;
	(void) reason;
	}

#if COMPILER_LIKES_PRAGMA_MARK
#pragma mark -
#pragma mark - /etc/hosts support
#endif

mDNSexport void FreeEtcHosts(mDNS *const m, AuthRecord *const rr, mStatus result)
    {
    (void)m;  // unused
	(void)rr;
	(void)result;
	}


#if COMPILER_LIKES_PRAGMA_MARK
#pragma mark ***** DDNS Config Platform Functions
#endif

mDNSexport void mDNSPlatformSetDNSConfig(mDNS *const m, mDNSBool setservers, mDNSBool setsearch, domainname *const fqdn, DNameListElem **RegDomains, DNameListElem **BrowseDomains)
	{
	(void) m;
	(void) setservers;
	(void) fqdn;
	(void) setsearch;
	(void) RegDomains;
	(void) BrowseDomains;
	}

mDNSexport mStatus mDNSPlatformGetPrimaryInterface(mDNS * const m, mDNSAddr * v4, mDNSAddr * v6, mDNSAddr * router)
	{
	(void) m;
	(void) v4;
	(void) v6;
	(void) router;

	return mStatus_UnsupportedErr;
	}

mDNSexport void mDNSPlatformDynDNSHostNameStatusChanged(const domainname *const dname, const mStatus status)
	{
	(void) dname;
	(void) status;
	}

#if COMPILER_LIKES_PRAGMA_MARK
#pragma mark ***** Init and Term
#endif

// This gets the current hostname, truncating it at the first dot if necessary
mDNSlocal void GetUserSpecifiedRFC1034ComputerName(domainlabel *const namelabel)
	{
	int len = 0;
	gethostname((char *)(&namelabel->c[1]), MAX_DOMAIN_LABEL);
	while (len < MAX_DOMAIN_LABEL && namelabel->c[len+1] && namelabel->c[len+1] != '.') len++;
	namelabel->c[0] = len;
	}

// On OS X this gets the text of the field labelled "Computer Name" in the Sharing Prefs Control Panel
// Other platforms can either get the information from the appropriate place,
// or they can alternatively just require all registering services to provide an explicit name
mDNSlocal void GetUserSpecifiedFriendlyComputerName(domainlabel *const namelabel)
	{
	// On Unix we have no better name than the host name, so we just use that.
	GetUserSpecifiedRFC1034ComputerName(namelabel);
	}

mDNSexport int ParseDNSServers(mDNS *m, const char *filePath)
	{
	char line[256];
	char nameserver[16];
	char keyword[10];
	int  numOfServers = 0;
	FILE *fp = fopen(filePath, "r");
	if (fp == NULL) return -1;
	while (fgets(line,sizeof(line),fp))
		{
		struct in_addr ina;
		line[255]='\0';		// just to be safe
		if (sscanf(line,"%10s %15s", keyword, nameserver) != 2) continue;	// it will skip whitespaces
		if (strncasecmp(keyword,"nameserver",10)) continue;
		if (inet_aton(nameserver, (struct in_addr *)&ina) != 0)
			{
			mDNSAddr DNSAddr;
			DNSAddr.type = mDNSAddrType_IPv4;
			DNSAddr.ip.v4.NotAnInteger = ina.s_addr;
			mDNS_AddDNSServer(m, NULL, mDNSInterface_Any, &DNSAddr, UnicastDNSPort, mDNSfalse, 0);
			numOfServers++;
			}
		}  
	return (numOfServers > 0) ? 0 : -1;
	}

// Searches the interface list looking for the named interface.
// Returns a pointer to if it found, or NULL otherwise.
mDNSlocal PosixNetworkInterface *SearchForInterfaceByName(mDNS *const m, const char *intfName)
	{
	PosixNetworkInterface *intf;

	assert(m != NULL);
	assert(intfName != NULL);

	intf = (PosixNetworkInterface*)(m->HostInterfaces);
	while ((intf != NULL) && (strcmp(intf->intfName, intfName) != 0))
		intf = (PosixNetworkInterface *)(intf->coreIntf.next);

	return intf;
	}

mDNSexport mDNSInterfaceID mDNSPlatformInterfaceIDfromInterfaceIndex(mDNS *const m, mDNSu32 index)
	{
	PosixNetworkInterface *intf;

	assert(m != NULL);

	if (index == kDNSServiceInterfaceIndexLocalOnly) return(mDNSInterface_LocalOnly);
	if (index == kDNSServiceInterfaceIndexP2P      ) return(mDNSInterface_P2P);
	if (index == kDNSServiceInterfaceIndexAny      ) return(mDNSInterface_Any);

	intf = (PosixNetworkInterface*)(m->HostInterfaces);
	while ((intf != NULL) && (mDNSu32) intf->index != index) 
		intf = (PosixNetworkInterface *)(intf->coreIntf.next);

	return (mDNSInterfaceID) intf;
	}
	
mDNSexport mDNSu32 mDNSPlatformInterfaceIndexfromInterfaceID(mDNS *const m, mDNSInterfaceID id, mDNSBool suppressNetworkChange)
	{
	PosixNetworkInterface *intf;
	(void) suppressNetworkChange; // Unused

	assert(m != NULL);

	if (id == mDNSInterface_LocalOnly) return(kDNSServiceInterfaceIndexLocalOnly);
	if (id == mDNSInterface_P2P      ) return(kDNSServiceInterfaceIndexP2P);
	if (id == mDNSInterface_Any      ) return(kDNSServiceInterfaceIndexAny);

	intf = (PosixNetworkInterface*)(m->HostInterfaces);
	while ((intf != NULL) && (mDNSInterfaceID) intf != id)
		intf = (PosixNetworkInterface *)(intf->coreIntf.next);

	return intf ? intf->index : 0;
	}

// Frees the specified PosixNetworkInterface structure. The underlying
// interface must have already been deregistered with the mDNS core.
mDNSlocal void FreePosixNetworkInterface(PosixNetworkInterface *intf)
	{
	assert(intf != NULL);
	if (intf->intfName != NULL)        free((void *)intf->intfName);
	if (intf->multicastSocket4 != -1) assert(close(intf->multicastSocket4) == 0);
#if HAVE_IPV6
	if (intf->multicastSocket6 != -1) assert(close(intf->multicastSocket6) == 0);
#endif
	free(intf);
	}

// Grab the first interface, deregister it, free it, and repeat until done.
mDNSlocal void ClearInterfaceList(mDNS *const m)
	{
	assert(m != NULL);

	while (m->HostInterfaces)
		{
		PosixNetworkInterface *intf = (PosixNetworkInterface*)(m->HostInterfaces);
		mDNS_DeregisterInterface(m, &intf->coreIntf, mDNSfalse);
		if (gMDNSPlatformPosixVerboseLevel > 0) fprintf(stderr, "Deregistered interface %s\n", intf->intfName);
		FreePosixNetworkInterface(intf);
		}
	num_registered_interfaces = 0;
	num_pkts_accepted = 0;
	num_pkts_rejected = 0;
	}

// Sets up a send/receive socket.
// If mDNSIPPort port is non-zero, then it's a multicast socket on the specified interface
// If mDNSIPPort port is zero, then it's a randomly assigned port number, used for sending unicast queries
mDNSlocal int SetupSocket(struct sockaddr *intfAddr, mDNSIPPort port, int interfaceIndex, int *sktPtr)
	{
	int err = 0;
	static const int kOn = 1;
	static const int kIntTwoFiveFive = 255;
	static const unsigned char kByteTwoFiveFive = 255;
	const mDNSBool JoinMulticastGroup = (port.NotAnInteger != 0);
	
	(void) interfaceIndex;	// This parameter unused on plaforms that don't have IPv6
	assert(intfAddr != NULL);
	assert(sktPtr != NULL);
	assert(*sktPtr == -1);

	// Open the socket...
	if      (intfAddr->sa_family == AF_INET) *sktPtr = socket(PF_INET,  SOCK_DGRAM, IPPROTO_UDP);
#if HAVE_IPV6
	else if (intfAddr->sa_family == AF_INET6) *sktPtr = socket(PF_INET6, SOCK_DGRAM, IPPROTO_UDP);
#endif
	else return EINVAL;

	if (*sktPtr < 0) { err = errno; perror((intfAddr->sa_family == AF_INET) ? "socket AF_INET" : "socket AF_INET6"); }

	// ... with a shared UDP port, if it's for multicast receiving
	if (err == 0 && port.NotAnInteger)
		{
		#if defined(SO_REUSEPORT)
			err = setsockopt(*sktPtr, SOL_SOCKET, SO_REUSEPORT, &kOn, sizeof(kOn));
		#elif defined(SO_REUSEADDR)
			err = setsockopt(*sktPtr, SOL_SOCKET, SO_REUSEADDR, &kOn, sizeof(kOn));
		#else
			#error This platform has no way to avoid address busy errors on multicast.
		#endif
		if (err < 0) { err = errno; perror("setsockopt - SO_REUSExxxx"); }
		}

	// We want to receive destination addresses and interface identifiers.
	if (intfAddr->sa_family == AF_INET)
		{
		struct ip_mreq imr;
		struct sockaddr_in bindAddr;
		if (err == 0)
			{
			#if defined(IP_PKTINFO)									// Linux
				err = setsockopt(*sktPtr, IPPROTO_IP, IP_PKTINFO, &kOn, sizeof(kOn));
				if (err < 0) { err = errno; perror("setsockopt - IP_PKTINFO"); }
			#elif defined(IP_RECVDSTADDR) || defined(IP_RECVIF)		// BSD and Solaris
				#if defined(IP_RECVDSTADDR)
					err = setsockopt(*sktPtr, IPPROTO_IP, IP_RECVDSTADDR, &kOn, sizeof(kOn));
					if (err < 0) { err = errno; perror("setsockopt - IP_RECVDSTADDR"); }
				#endif
				#if defined(IP_RECVIF)
					if (err == 0)
						{
						err = setsockopt(*sktPtr, IPPROTO_IP, IP_RECVIF, &kOn, sizeof(kOn));
						if (err < 0) { err = errno; perror("setsockopt - IP_RECVIF"); }
						}
				#endif
			#else
				#warning This platform has no way to get the destination interface information -- will only work for single-homed hosts
			#endif
			}
	#if defined(IP_RECVTTL)									// Linux
		if (err == 0)
			{
			setsockopt(*sktPtr, IPPROTO_IP, IP_RECVTTL, &kOn, sizeof(kOn));
			// We no longer depend on being able to get the received TTL, so don't worry if the option fails
			}
	#endif
		// Add multicast group membership on this interface
		if (err == 0 && JoinMulticastGroup)
			{
			imr.imr_multiaddr.s_addr = AllDNSLinkGroup_v4.ip.v4.NotAnInteger;
			imr.imr_interface        = ((struct sockaddr_in*)intfAddr)->sin_addr;
			err = setsockopt(*sktPtr, IPPROTO_IP, IP_ADD_MEMBERSHIP, &imr, sizeof(imr));
			if (err < 0) { err = errno; perror("setsockopt - IP_ADD_MEMBERSHIP"); }
			}

		// Specify outgoing interface too
		if (err == 0 && JoinMulticastGroup)
			{
			err = setsockopt(*sktPtr, IPPROTO_IP, IP_MULTICAST_IF, &((struct sockaddr_in*)intfAddr)->sin_addr, sizeof(struct in_addr));
			if (err < 0) { err = errno; perror("setsockopt - IP_MULTICAST_IF"); }
			}

		// Per the mDNS spec, send unicast packets with TTL 255
		if (err == 0)
			{
			err = setsockopt(*sktPtr, IPPROTO_IP, IP_TTL, &kIntTwoFiveFive, sizeof(kIntTwoFiveFive));
			if (err < 0) { err = errno; perror("setsockopt - IP_TTL"); }
			}

		// and multicast packets with TTL 255 too
		// There's some debate as to whether IP_MULTICAST_TTL is an int or a byte so we just try both.
		if (err == 0)
			{
			err = setsockopt(*sktPtr, IPPROTO_IP, IP_MULTICAST_TTL, &kByteTwoFiveFive, sizeof(kByteTwoFiveFive));
			if (err < 0 && errno == EINVAL)
				err = setsockopt(*sktPtr, IPPROTO_IP, IP_MULTICAST_TTL, &kIntTwoFiveFive, sizeof(kIntTwoFiveFive));
			if (err < 0) { err = errno; perror("setsockopt - IP_MULTICAST_TTL"); }
			}

		// And start listening for packets
		if (err == 0)
			{
			bindAddr.sin_family      = AF_INET;
			bindAddr.sin_port        = port.NotAnInteger;
			bindAddr.sin_addr.s_addr = INADDR_ANY; // Want to receive multicasts AND unicasts on this socket
			err = bind(*sktPtr, (struct sockaddr *) &bindAddr, sizeof(bindAddr));
			if (err < 0) { err = errno; perror("bind"); fflush(stderr); }
			}
		} // endif (intfAddr->sa_family == AF_INET)

#if HAVE_IPV6
	else if (intfAddr->sa_family == AF_INET6)
		{
		struct ipv6_mreq imr6;
		struct sockaddr_in6 bindAddr6;
	#if defined(IPV6_PKTINFO)
		if (err == 0)
			{
				err = setsockopt(*sktPtr, IPPROTO_IPV6, IPV6_2292_PKTINFO, &kOn, sizeof(kOn));
				if (err < 0) { err = errno; perror("setsockopt - IPV6_PKTINFO"); }
			}
	#else
		#warning This platform has no way to get the destination interface information for IPv6 -- will only work for single-homed hosts
	#endif
	#if defined(IPV6_HOPLIMIT)
		if (err == 0)
			{
				err = setsockopt(*sktPtr, IPPROTO_IPV6, IPV6_2292_HOPLIMIT, &kOn, sizeof(kOn));
				if (err < 0) { err = errno; perror("setsockopt - IPV6_HOPLIMIT"); }
			}
	#endif

		// Add multicast group membership on this interface
		if (err == 0 && JoinMulticastGroup)
			{
			imr6.ipv6mr_multiaddr       = *(const struct in6_addr*)&AllDNSLinkGroup_v6.ip.v6;
			imr6.ipv6mr_interface       = interfaceIndex;
			//LogMsg("Joining %.16a on %d", &imr6.ipv6mr_multiaddr, imr6.ipv6mr_interface);
			err = setsockopt(*sktPtr, IPPROTO_IPV6, IPV6_JOIN_GROUP, &imr6, sizeof(imr6));
			if (err < 0)
				{
				err = errno;
				verbosedebugf("IPV6_JOIN_GROUP %.16a on %d failed.\n", &imr6.ipv6mr_multiaddr, imr6.ipv6mr_interface);
				perror("setsockopt - IPV6_JOIN_GROUP");
				}
			}

		// Specify outgoing interface too
		if (err == 0 && JoinMulticastGroup)
			{
			u_int	multicast_if = interfaceIndex;
			err = setsockopt(*sktPtr, IPPROTO_IPV6, IPV6_MULTICAST_IF, &multicast_if, sizeof(multicast_if));
			if (err < 0) { err = errno; perror("setsockopt - IPV6_MULTICAST_IF"); }
			}

		// We want to receive only IPv6 packets on this socket.
		// Without this option, we may get IPv4 addresses as mapped addresses.
		if (err == 0)
			{
			err = setsockopt(*sktPtr, IPPROTO_IPV6, IPV6_V6ONLY, &kOn, sizeof(kOn));
			if (err < 0) { err = errno; perror("setsockopt - IPV6_V6ONLY"); }
			}

		// Per the mDNS spec, send unicast packets with TTL 255
		if (err == 0)
			{
			err = setsockopt(*sktPtr, IPPROTO_IPV6, IPV6_UNICAST_HOPS, &kIntTwoFiveFive, sizeof(kIntTwoFiveFive));
			if (err < 0) { err = errno; perror("setsockopt - IPV6_UNICAST_HOPS"); }
			}

		// and multicast packets with TTL 255 too
		// There's some debate as to whether IPV6_MULTICAST_HOPS is an int or a byte so we just try both.
		if (err == 0)
			{
			err = setsockopt(*sktPtr, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, &kByteTwoFiveFive, sizeof(kByteTwoFiveFive));
			if (err < 0 && errno == EINVAL)
				err = setsockopt(*sktPtr, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, &kIntTwoFiveFive, sizeof(kIntTwoFiveFive));
			if (err < 0) { err = errno; perror("setsockopt - IPV6_MULTICAST_HOPS"); }
			}

		// And start listening for packets
		if (err == 0)
			{
			mDNSPlatformMemZero(&bindAddr6, sizeof(bindAddr6));
#ifndef NOT_HAVE_SA_LEN
			bindAddr6.sin6_len         = sizeof(bindAddr6);
#endif
			bindAddr6.sin6_family      = AF_INET6;
			bindAddr6.sin6_port        = port.NotAnInteger;
			bindAddr6.sin6_flowinfo    = 0;
			bindAddr6.sin6_addr        = in6addr_any; // Want to receive multicasts AND unicasts on this socket
			bindAddr6.sin6_scope_id    = 0;
			err = bind(*sktPtr, (struct sockaddr *) &bindAddr6, sizeof(bindAddr6));
			if (err < 0) { err = errno; perror("bind"); fflush(stderr); }
			}
		} // endif (intfAddr->sa_family == AF_INET6)
#endif

	// Set the socket to non-blocking.
	if (err == 0)
		{
		err = fcntl(*sktPtr, F_GETFL, 0);
		if (err < 0) err = errno;
		else
			{
			err = fcntl(*sktPtr, F_SETFL, err | O_NONBLOCK);
			if (err < 0) err = errno;
			}
		}

	// Clean up
	if (err != 0 && *sktPtr != -1) { assert(close(*sktPtr) == 0); *sktPtr = -1; }
	assert((err == 0) == (*sktPtr != -1));
	return err;
	}

// Creates a PosixNetworkInterface for the interface whose IP address is
// intfAddr and whose name is intfName and registers it with mDNS core.
mDNSlocal int SetupOneInterface(mDNS *const m, struct sockaddr *intfAddr, struct sockaddr *intfMask, const char *intfName, int intfIndex)
	{
	int err = 0;
	PosixNetworkInterface *intf;
	PosixNetworkInterface *alias = NULL;

	assert(m != NULL);
	assert(intfAddr != NULL);
	assert(intfName != NULL);
	assert(intfMask != NULL);

	// Allocate the interface structure itself.
	intf = (PosixNetworkInterface*)malloc(sizeof(*intf));
	if (intf == NULL) { assert(0); err = ENOMEM; }

	// And make a copy of the intfName.
	if (err == 0)
		{
		intf->intfName = strdup(intfName);
		if (intf->intfName == NULL) { assert(0); err = ENOMEM; }
		}

	if (err == 0)
		{
		// Set up the fields required by the mDNS core.
		SockAddrTomDNSAddr(intfAddr, &intf->coreIntf.ip, NULL);
		SockAddrTomDNSAddr(intfMask, &intf->coreIntf.mask, NULL);

		//LogMsg("SetupOneInterface: %#a %#a",  &intf->coreIntf.ip,  &intf->coreIntf.mask);
		strncpy(intf->coreIntf.ifname, intfName, sizeof(intf->coreIntf.ifname));
		intf->coreIntf.ifname[sizeof(intf->coreIntf.ifname)-1] = 0;
		intf->coreIntf.Advertise = m->AdvertiseLocalAddresses;
		intf->coreIntf.McastTxRx = mDNStrue;

		// Set up the extra fields in PosixNetworkInterface.
		assert(intf->intfName != NULL);         // intf->intfName already set up above
		intf->index                = intfIndex;
		intf->multicastSocket4     = -1;
#if HAVE_IPV6
		intf->multicastSocket6     = -1;
#endif
		alias                      = SearchForInterfaceByName(m, intf->intfName);
		if (alias == NULL) alias   = intf;
		intf->coreIntf.InterfaceID = (mDNSInterfaceID)alias;

		if (alias != intf)
			debugf("SetupOneInterface: %s %#a is an alias of %#a", intfName, &intf->coreIntf.ip, &alias->coreIntf.ip);
		}

	// Set up the multicast socket
	if (err == 0)
		{
		if (alias->multicastSocket4 == -1 && intfAddr->sa_family == AF_INET)
			err = SetupSocket(intfAddr, MulticastDNSPort, intf->index, &alias->multicastSocket4);
#if HAVE_IPV6
		else if (alias->multicastSocket6 == -1 && intfAddr->sa_family == AF_INET6)
			err = SetupSocket(intfAddr, MulticastDNSPort, intf->index, &alias->multicastSocket6);
#endif
		}

	// The interface is all ready to go, let's register it with the mDNS core.
	if (err == 0)
		err = mDNS_RegisterInterface(m, &intf->coreIntf, mDNSfalse);

	// Clean up.
	if (err == 0)
		{
		num_registered_interfaces++;
		debugf("SetupOneInterface: %s %#a Registered", intf->intfName, &intf->coreIntf.ip);
		if (gMDNSPlatformPosixVerboseLevel > 0)
			fprintf(stderr, "Registered interface %s\n", intf->intfName);
		}
	else
		{
		// Use intfName instead of intf->intfName in the next line to avoid dereferencing NULL.
		debugf("SetupOneInterface: %s %#a failed to register %d", intfName, &intf->coreIntf.ip, err);
		if (intf) { FreePosixNetworkInterface(intf); intf = NULL; }
		}

	assert((err == 0) == (intf != NULL));

	return err;
	}

// Call get_ifi_info() to obtain a list of active interfaces and call SetupOneInterface() on each one.
mDNSlocal int SetupInterfaceList(mDNS *const m)
	{
	mDNSBool        foundav4       = mDNSfalse;
	int             err            = 0;
	struct ifi_info *intfList      = get_ifi_info(AF_INET, mDNStrue);
	struct ifi_info *firstLoopback = NULL;

	assert(m != NULL);
	debugf("SetupInterfaceList");

	if (intfList == NULL) err = ENOENT;

#if HAVE_IPV6
	if (err == 0)		/* Link the IPv6 list to the end of the IPv4 list */
		{
		struct ifi_info **p = &intfList;
		while (*p) p = &(*p)->ifi_next;
		*p = get_ifi_info(AF_INET6, mDNStrue);
		}
#endif

	if (err == 0)
		{
		struct ifi_info *i = intfList;
		while (i)
			{
			if (     ((i->ifi_addr->sa_family == AF_INET)
#if HAVE_IPV6
					  || (i->ifi_addr->sa_family == AF_INET6)
#endif
				) &&  (i->ifi_flags & IFF_UP) && !(i->ifi_flags & IFF_POINTOPOINT))
				{
				if (i->ifi_flags & IFF_LOOPBACK)
					{
					if (firstLoopback == NULL)
						firstLoopback = i;
					}
				else
					{
					if (SetupOneInterface(m, i->ifi_addr, i->ifi_netmask, i->ifi_name, i->ifi_index) == 0)
						if (i->ifi_addr->sa_family == AF_INET)
							foundav4 = mDNStrue;
					}
				}
			i = i->ifi_next;
			}

		// If we found no normal interfaces but we did find a loopback interface, register the
		// loopback interface.  This allows self-discovery if no interfaces are configured.
		// Temporary workaround: Multicast loopback on IPv6 interfaces appears not to work.
		// In the interim, we skip loopback interface only if we found at least one v4 interface to use
		// if ((m->HostInterfaces == NULL) && (firstLoopback != NULL))
		if (!foundav4 && firstLoopback)
			(void) SetupOneInterface(m, firstLoopback->ifi_addr, firstLoopback->ifi_netmask, firstLoopback->ifi_name, firstLoopback->ifi_index);
		}

	// Clean up.
	if (intfList != NULL) free_ifi_info(intfList);
	return err;
	}

#if USES_NETLINK

// See <http://www.faqs.org/rfcs/rfc3549.html> for a description of NetLink

// Open a socket that will receive interface change notifications
mDNSlocal mStatus OpenIfNotifySocket(int *pFD)
	{
	mStatus					err = mStatus_NoError;
	struct sockaddr_nl		snl;
	int sock;
	int ret;

	sock = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
	if (sock < 0)
		return errno;

	// Configure read to be non-blocking because inbound msg size is not known in advance
	(void) fcntl(sock, F_SETFL, O_NONBLOCK);

	/* Subscribe the socket to Link & IP addr notifications. */
	mDNSPlatformMemZero(&snl, sizeof snl);
	snl.nl_family = AF_NETLINK;
	snl.nl_groups = RTMGRP_LINK | RTMGRP_IPV4_IFADDR;
	ret = bind(sock, (struct sockaddr *) &snl, sizeof snl);
	if (0 == ret)
		*pFD = sock;
	else
		err = errno;

	return err;
	}

#if MDNS_DEBUGMSGS
mDNSlocal void		PrintNetLinkMsg(const struct nlmsghdr *pNLMsg)
	{
	const char *kNLMsgTypes[] = { "", "NLMSG_NOOP", "NLMSG_ERROR", "NLMSG_DONE", "NLMSG_OVERRUN" };
	const char *kNLRtMsgTypes[] = { "RTM_NEWLINK", "RTM_DELLINK", "RTM_GETLINK", "RTM_NEWADDR", "RTM_DELADDR", "RTM_GETADDR" };

	printf("nlmsghdr len=%d, type=%s, flags=0x%x\n", pNLMsg->nlmsg_len, 
			pNLMsg->nlmsg_type < RTM_BASE ? kNLMsgTypes[pNLMsg->nlmsg_type] : kNLRtMsgTypes[pNLMsg->nlmsg_type - RTM_BASE], 
			pNLMsg->nlmsg_flags);

	if (RTM_NEWLINK <= pNLMsg->nlmsg_type && pNLMsg->nlmsg_type <= RTM_GETLINK)
		{
		struct ifinfomsg	*pIfInfo = (struct ifinfomsg*) NLMSG_DATA(pNLMsg);
		printf("ifinfomsg family=%d, type=%d, index=%d, flags=0x%x, change=0x%x\n", pIfInfo->ifi_family, 
				pIfInfo->ifi_type, pIfInfo->ifi_index, pIfInfo->ifi_flags, pIfInfo->ifi_change);
		
		}
	else if (RTM_NEWADDR <= pNLMsg->nlmsg_type && pNLMsg->nlmsg_type <= RTM_GETADDR)
		{
		struct ifaddrmsg	*pIfAddr = (struct ifaddrmsg*) NLMSG_DATA(pNLMsg);
		printf("ifaddrmsg family=%d, index=%d, flags=0x%x\n", pIfAddr->ifa_family, 
				pIfAddr->ifa_index, pIfAddr->ifa_flags);
		}
	printf("\n");
	}
#endif

mDNSlocal mDNSu32		ProcessRoutingNotification(int sd)
// Read through the messages on sd and if any indicate that any interface records should
// be torn down and rebuilt, return affected indices as a bitmask. Otherwise return 0.
	{
	ssize_t					readCount;
	char					buff[4096];	
	struct nlmsghdr			*pNLMsg = (struct nlmsghdr*) buff;
	mDNSu32				result = 0;
	
	// The structure here is more complex than it really ought to be because,
	// unfortunately, there's no good way to size a buffer in advance large
	// enough to hold all pending data and so avoid message fragmentation.
	// (Note that FIONREAD is not supported on AF_NETLINK.)

	readCount = read(sd, buff, sizeof buff);
	while (1)
		{
		// Make sure we've got an entire nlmsghdr in the buffer, and payload, too.
		// If not, discard already-processed messages in buffer and read more data.
		if (((char*) &pNLMsg[1] > (buff + readCount)) ||	// i.e. *pNLMsg extends off end of buffer 
			 ((char*) pNLMsg + pNLMsg->nlmsg_len > (buff + readCount)))
			{
			if (buff < (char*) pNLMsg)		// we have space to shuffle
				{
				// discard processed data
				readCount -= ((char*) pNLMsg - buff);
				memmove(buff, pNLMsg, readCount);
				pNLMsg = (struct nlmsghdr*) buff;

				// read more data
				readCount += read(sd, buff + readCount, sizeof buff - readCount);
				continue;					// spin around and revalidate with new readCount
				}
			else
				break;	// Otherwise message does not fit in buffer
			}

#if MDNS_DEBUGMSGS
		PrintNetLinkMsg(pNLMsg);
#endif

		// Process the NetLink message
		if (pNLMsg->nlmsg_type == RTM_GETLINK || pNLMsg->nlmsg_type == RTM_NEWLINK)
			result |= 1 << ((struct ifinfomsg*) NLMSG_DATA(pNLMsg))->ifi_index;
		else if (pNLMsg->nlmsg_type == RTM_DELADDR || pNLMsg->nlmsg_type == RTM_NEWADDR)
			result |= 1 << ((struct ifaddrmsg*) NLMSG_DATA(pNLMsg))->ifa_index;

		// Advance pNLMsg to the next message in the buffer
		if ((pNLMsg->nlmsg_flags & NLM_F_MULTI) != 0 && pNLMsg->nlmsg_type != NLMSG_DONE)
			{
			ssize_t	len = readCount - ((char*)pNLMsg - buff);
			pNLMsg = NLMSG_NEXT(pNLMsg, len);
			}
		else
			break;	// all done!
		}

	return result;
	}

#else // USES_NETLINK

// Open a socket that will receive interface change notifications
mDNSlocal mStatus OpenIfNotifySocket(int *pFD)
	{
	*pFD = socket(AF_ROUTE, SOCK_RAW, 0);

	if (*pFD < 0)
		return mStatus_UnknownErr;

	// Configure read to be non-blocking because inbound msg size is not known in advance
	(void) fcntl(*pFD, F_SETFL, O_NONBLOCK);

	return mStatus_NoError;
	}

#if MDNS_DEBUGMSGS
mDNSlocal void		PrintRoutingSocketMsg(const struct ifa_msghdr *pRSMsg)
	{
	const char *kRSMsgTypes[] = { "", "RTM_ADD", "RTM_DELETE", "RTM_CHANGE", "RTM_GET", "RTM_LOSING",
					"RTM_REDIRECT", "RTM_MISS", "RTM_LOCK", "RTM_OLDADD", "RTM_OLDDEL", "RTM_RESOLVE", 
					"RTM_NEWADDR", "RTM_DELADDR", "RTM_IFINFO", "RTM_NEWMADDR", "RTM_DELMADDR" };

	int		index = pRSMsg->ifam_type == RTM_IFINFO ? ((struct if_msghdr*) pRSMsg)->ifm_index : pRSMsg->ifam_index;

	printf("ifa_msghdr len=%d, type=%s, index=%d\n", pRSMsg->ifam_msglen, kRSMsgTypes[pRSMsg->ifam_type], index);
	}
#endif

mDNSlocal mDNSu32		ProcessRoutingNotification(int sd)
// Read through the messages on sd and if any indicate that any interface records should
// be torn down and rebuilt, return affected indices as a bitmask. Otherwise return 0.
	{
	ssize_t					readCount;
	char					buff[4096];	
	struct ifa_msghdr		*pRSMsg = (struct ifa_msghdr*) buff;
	mDNSu32				result = 0;

	readCount = read(sd, buff, sizeof buff);
	if (readCount < (ssize_t) sizeof(struct ifa_msghdr))
		return mStatus_UnsupportedErr;		// cannot decipher message

#if MDNS_DEBUGMSGS
	PrintRoutingSocketMsg(pRSMsg);
#endif

	// Process the message
	if (pRSMsg->ifam_type == RTM_NEWADDR || pRSMsg->ifam_type == RTM_DELADDR ||
		 pRSMsg->ifam_type == RTM_IFINFO)
		{
		if (pRSMsg->ifam_type == RTM_IFINFO)
			result |= 1 << ((struct if_msghdr*) pRSMsg)->ifm_index;
		else
			result |= 1 << pRSMsg->ifam_index;
		}

	return result;
	}

#endif // USES_NETLINK

// Called when data appears on interface change notification socket
mDNSlocal void InterfaceChangeCallback(int fd, short filter, void *context)
	{
	IfChangeRec		*pChgRec = (IfChangeRec*) context;
	fd_set			readFDs;
	mDNSu32		changedInterfaces = 0;
	struct timeval	zeroTimeout = { 0, 0 };

	(void)fd; // Unused
	(void)filter; // Unused

	FD_ZERO(&readFDs);
	FD_SET(pChgRec->NotifySD, &readFDs);

	do
	{
		changedInterfaces |= ProcessRoutingNotification(pChgRec->NotifySD);
	}
	while (0 < select(pChgRec->NotifySD + 1, &readFDs, (fd_set*) NULL, (fd_set*) NULL, &zeroTimeout));

	// Currently we rebuild the entire interface list whenever any interface change is
	// detected. If this ever proves to be a performance issue in a multi-homed 
	// configuration, more care should be paid to changedInterfaces.
	if (changedInterfaces)
		mDNSPlatformPosixRefreshInterfaceList(pChgRec->mDNS);
	}

// Register with either a Routing Socket or RtNetLink to listen for interface changes.
mDNSlocal mStatus WatchForInterfaceChange(mDNS *const m)
	{
	mStatus		err;
	IfChangeRec	*pChgRec;

	pChgRec = (IfChangeRec*) mDNSPlatformMemAllocate(sizeof *pChgRec);
	if (pChgRec == NULL)
		return mStatus_NoMemoryErr;

	pChgRec->mDNS = m;
	err = OpenIfNotifySocket(&pChgRec->NotifySD);
	if (err == 0)
		err = mDNSPosixAddFDToEventLoop(pChgRec->NotifySD, InterfaceChangeCallback, pChgRec);

	return err;
	}

// Test to see if we're the first client running on UDP port 5353, by trying to bind to 5353 without using SO_REUSEPORT.
// If we fail, someone else got here first. That's not a big problem; we can share the port for multicast responses --
// we just need to be aware that we shouldn't expect to successfully receive unicast UDP responses.
mDNSlocal mDNSBool mDNSPlatformInit_CanReceiveUnicast(void)
	{
	int err;
	int s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
	struct sockaddr_in s5353;
	s5353.sin_family      = AF_INET;
	s5353.sin_port        = MulticastDNSPort.NotAnInteger;
	s5353.sin_addr.s_addr = 0;
	err = bind(s, (struct sockaddr *)&s5353, sizeof(s5353));
	close(s);
	if (err) debugf("No unicast UDP responses");
	else     debugf("Unicast UDP responses okay");
	return(err == 0);
	}

// mDNS core calls this routine to initialise the platform-specific data.
mDNSexport mStatus mDNSPlatformInit(mDNS *const m)
	{
	int err = 0;
	struct sockaddr sa;
	assert(m != NULL);

	if (mDNSPlatformInit_CanReceiveUnicast()) m->CanReceiveUnicastOn5353 = mDNStrue;

	// Tell mDNS core the names of this machine.

	// Set up the nice label
	m->nicelabel.c[0] = 0;
	GetUserSpecifiedFriendlyComputerName(&m->nicelabel);
	if (m->nicelabel.c[0] == 0) MakeDomainLabelFromLiteralString(&m->nicelabel, "Computer");

	// Set up the RFC 1034-compliant label
	m->hostlabel.c[0] = 0;
	GetUserSpecifiedRFC1034ComputerName(&m->hostlabel);
	if (m->hostlabel.c[0] == 0) MakeDomainLabelFromLiteralString(&m->hostlabel, "Computer");

	mDNS_SetFQDN(m);

	sa.sa_family = AF_INET;
	m->p->unicastSocket4 = -1;
	if (err == mStatus_NoError) err = SetupSocket(&sa, zeroIPPort, 0, &m->p->unicastSocket4);
#if HAVE_IPV6
	sa.sa_family = AF_INET6;
	m->p->unicastSocket6 = -1;
	if (err == mStatus_NoError) err = SetupSocket(&sa, zeroIPPort, 0, &m->p->unicastSocket6);
#endif

	// Tell mDNS core about the network interfaces on this machine.
	if (err == mStatus_NoError) err = SetupInterfaceList(m);

	// Tell mDNS core about DNS Servers
	mDNS_Lock(m);
	if (err == mStatus_NoError) ParseDNSServers(m, uDNS_SERVERS_FILE);
	mDNS_Unlock(m);

	if (err == mStatus_NoError)
		{
		err = WatchForInterfaceChange(m);
		// Failure to observe interface changes is non-fatal.
		if (err != mStatus_NoError)
			{
			fprintf(stderr, "mDNS(%d) WARNING: Unable to detect interface changes (%d).\n", getpid(), err);
			err = mStatus_NoError;
			}
		}

	// We don't do asynchronous initialization on the Posix platform, so by the time
	// we get here the setup will already have succeeded or failed.  If it succeeded,
	// we should just call mDNSCoreInitComplete() immediately.
	if (err == mStatus_NoError)
		mDNSCoreInitComplete(m, mStatus_NoError);

	return PosixErrorToStatus(err);
	}

// mDNS core calls this routine to clean up the platform-specific data.
// In our case all we need to do is to tear down every network interface.
mDNSexport void mDNSPlatformClose(mDNS *const m)
	{
	assert(m != NULL);
	ClearInterfaceList(m);
	if (m->p->unicastSocket4 != -1) assert(close(m->p->unicastSocket4) == 0);
#if HAVE_IPV6
	if (m->p->unicastSocket6 != -1) assert(close(m->p->unicastSocket6) == 0);
#endif
	}

mDNSexport mStatus mDNSPlatformPosixRefreshInterfaceList(mDNS *const m)
	{
	int err;
	ClearInterfaceList(m);
	err = SetupInterfaceList(m);
	return PosixErrorToStatus(err);
	}

#if COMPILER_LIKES_PRAGMA_MARK
#pragma mark ***** Locking
#endif

// On the Posix platform, locking is a no-op because we only ever enter
// mDNS core on the main thread.

// mDNS core calls this routine when it wants to prevent
// the platform from reentering mDNS core code.
mDNSexport void    mDNSPlatformLock   (const mDNS *const m)
	{
	(void) m;	// Unused
	}

// mDNS core calls this routine when it release the lock taken by
// mDNSPlatformLock and allow the platform to reenter mDNS core code.
mDNSexport void    mDNSPlatformUnlock (const mDNS *const m)
	{
	(void) m;	// Unused
	}

#if COMPILER_LIKES_PRAGMA_MARK
#pragma mark ***** Strings
#endif

// mDNS core calls this routine to copy C strings.
// On the Posix platform this maps directly to the ANSI C strcpy.
mDNSexport void    mDNSPlatformStrCopy(void *dst, const void *src)
	{
	strcpy((char *)dst, (char *)src);
	}

// mDNS core calls this routine to get the length of a C string.
// On the Posix platform this maps directly to the ANSI C strlen.
mDNSexport mDNSu32  mDNSPlatformStrLen (const void *src)
	{
	return strlen((char*)src);
	}

// mDNS core calls this routine to copy memory.
// On the Posix platform this maps directly to the ANSI C memcpy.
mDNSexport void    mDNSPlatformMemCopy(void *dst, const void *src, mDNSu32 len)
	{
	memcpy(dst, src, len);
	}

// mDNS core calls this routine to test whether blocks of memory are byte-for-byte
// identical. On the Posix platform this is a simple wrapper around ANSI C memcmp.
mDNSexport mDNSBool mDNSPlatformMemSame(const void *dst, const void *src, mDNSu32 len)
	{
	return memcmp(dst, src, len) == 0;
	}

// mDNS core calls this routine to clear blocks of memory.
// On the Posix platform this is a simple wrapper around ANSI C memset.
mDNSexport void    mDNSPlatformMemZero(void *dst, mDNSu32 len)
	{
	memset(dst, 0, len);
	}

mDNSexport void *  mDNSPlatformMemAllocate(mDNSu32 len) { return(malloc(len)); }
mDNSexport void    mDNSPlatformMemFree    (void *mem)   { free(mem); }

mDNSexport mDNSu32 mDNSPlatformRandomSeed(void)
	{
	struct timeval tv;
	gettimeofday(&tv, NULL);
	return(tv.tv_usec);
	}

mDNSexport mDNSs32  mDNSPlatformOneSecond = 1024;

mDNSexport mStatus mDNSPlatformTimeInit(void)
	{
	// No special setup is required on Posix -- we just use gettimeofday();
	// This is not really safe, because gettimeofday can go backwards if the user manually changes the date or time
	// We should find a better way to do this
	return(mStatus_NoError);
	}

mDNSexport mDNSs32  mDNSPlatformRawTime()
	{
	struct timeval tv;
	gettimeofday(&tv, NULL);
	// tv.tv_sec is seconds since 1st January 1970 (GMT, with no adjustment for daylight savings time)
	// tv.tv_usec is microseconds since the start of this second (i.e. values 0 to 999999)
	// We use the lower 22 bits of tv.tv_sec for the top 22 bits of our result
	// and we multiply tv.tv_usec by 16 / 15625 to get a value in the range 0-1023 to go in the bottom 10 bits.
	// This gives us a proper modular (cyclic) counter that has a resolution of roughly 1ms (actually 1/1024 second)
	// and correctly cycles every 2^22 seconds (4194304 seconds = approx 48 days).
	return((tv.tv_sec << 10) | (tv.tv_usec * 16 / 15625));
	}

mDNSexport mDNSs32 mDNSPlatformUTC(void)
	{
	return time(NULL);
	}

mDNSexport void mDNSPlatformSendWakeupPacket(mDNS *const m, mDNSInterfaceID InterfaceID, char *EthAddr, char *IPAddr, int iteration)
	{
	(void) m;
	(void) InterfaceID;
	(void) EthAddr;
	(void) IPAddr;
	(void) iteration;
	}

mDNSexport mDNSBool mDNSPlatformValidRecordForInterface(AuthRecord *rr, const NetworkInterfaceInfo *intf)
	{
	(void) rr;
	(void) intf;

	return 1;
	}

mDNSlocal void mDNSPosixAddToFDSet(int *nfds, fd_set *readfds, int s)
	{
	if (*nfds < s + 1) *nfds = s + 1;
	FD_SET(s, readfds);
	}

mDNSexport void mDNSPosixGetFDSet(mDNS *m, int *nfds, fd_set *readfds, struct timeval *timeout)
	{
	mDNSs32 ticks;
	struct timeval interval;

	// 1. Call mDNS_Execute() to let mDNSCore do what it needs to do
	mDNSs32 nextevent = mDNS_Execute(m);

	// 2. Build our list of active file descriptors
	PosixNetworkInterface *info = (PosixNetworkInterface *)(m->HostInterfaces);
	if (m->p->unicastSocket4 != -1) mDNSPosixAddToFDSet(nfds, readfds, m->p->unicastSocket4);
#if HAVE_IPV6
	if (m->p->unicastSocket6 != -1) mDNSPosixAddToFDSet(nfds, readfds, m->p->unicastSocket6);
#endif
	while (info)
		{
		if (info->multicastSocket4 != -1) mDNSPosixAddToFDSet(nfds, readfds, info->multicastSocket4);
#if HAVE_IPV6
		if (info->multicastSocket6 != -1) mDNSPosixAddToFDSet(nfds, readfds, info->multicastSocket6);
#endif
		info = (PosixNetworkInterface *)(info->coreIntf.next);
		}

	// 3. Calculate the time remaining to the next scheduled event (in struct timeval format)
	ticks = nextevent - mDNS_TimeNow(m);
	if (ticks < 1) ticks = 1;
	interval.tv_sec  = ticks >> 10;						// The high 22 bits are seconds
	interval.tv_usec = ((ticks & 0x3FF) * 15625) / 16;	// The low 10 bits are 1024ths

	// 4. If client's proposed timeout is more than what we want, then reduce it
	if (timeout->tv_sec > interval.tv_sec ||
		(timeout->tv_sec == interval.tv_sec && timeout->tv_usec > interval.tv_usec))
		*timeout = interval;
	}

mDNSexport void mDNSPosixProcessFDSet(mDNS *const m, fd_set *readfds)
	{
	PosixNetworkInterface *info;
	assert(m       != NULL);
	assert(readfds != NULL);
	info = (PosixNetworkInterface *)(m->HostInterfaces);

	if (m->p->unicastSocket4 != -1 && FD_ISSET(m->p->unicastSocket4, readfds))
		{
		FD_CLR(m->p->unicastSocket4, readfds);
		SocketDataReady(m, NULL, m->p->unicastSocket4);
		}
#if HAVE_IPV6
	if (m->p->unicastSocket6 != -1 && FD_ISSET(m->p->unicastSocket6, readfds))
		{
		FD_CLR(m->p->unicastSocket6, readfds);
		SocketDataReady(m, NULL, m->p->unicastSocket6);
		}
#endif

	while (info)
		{
		if (info->multicastSocket4 != -1 && FD_ISSET(info->multicastSocket4, readfds))
			{
			FD_CLR(info->multicastSocket4, readfds);
			SocketDataReady(m, info, info->multicastSocket4);
			}
#if HAVE_IPV6
		if (info->multicastSocket6 != -1 && FD_ISSET(info->multicastSocket6, readfds))
			{
			FD_CLR(info->multicastSocket6, readfds);
			SocketDataReady(m, info, info->multicastSocket6);
			}
#endif
		info = (PosixNetworkInterface *)(info->coreIntf.next);
		}
	}

// update gMaxFD
mDNSlocal void	DetermineMaxEventFD(void)
	{
	PosixEventSource	*iSource;
	
	gMaxFD = 0;
	for (iSource=(PosixEventSource*)gEventSources.Head; iSource; iSource = iSource->Next)
		if (gMaxFD < iSource->fd)
			gMaxFD = iSource->fd;
	}

// Add a file descriptor to the set that mDNSPosixRunEventLoopOnce() listens to.
mStatus mDNSPosixAddFDToEventLoop(int fd, mDNSPosixEventCallback callback, void *context)
	{
	PosixEventSource	*newSource;
	
	if (gEventSources.LinkOffset == 0)
		InitLinkedList(&gEventSources, offsetof(PosixEventSource, Next));

	if (fd >= (int) FD_SETSIZE || fd < 0)
		return mStatus_UnsupportedErr;
	if (callback == NULL)
		return mStatus_BadParamErr;

	newSource = (PosixEventSource*) malloc(sizeof *newSource);
	if (NULL == newSource)
		return mStatus_NoMemoryErr;

	newSource->Callback = callback;
	newSource->Context = context;
	newSource->fd = fd;

	AddToTail(&gEventSources, newSource);
	FD_SET(fd, &gEventFDs);

	DetermineMaxEventFD();

	return mStatus_NoError;
	}

// Remove a file descriptor from the set that mDNSPosixRunEventLoopOnce() listens to.
mStatus mDNSPosixRemoveFDFromEventLoop(int fd)
	{
	PosixEventSource	*iSource;
	
	for (iSource=(PosixEventSource*)gEventSources.Head; iSource; iSource = iSource->Next)
		{
		if (fd == iSource->fd)
			{
			FD_CLR(fd, &gEventFDs);
			RemoveFromList(&gEventSources, iSource);
			free(iSource);
			DetermineMaxEventFD();
			return mStatus_NoError;
			}
		}
	return mStatus_NoSuchNameErr;
	}

// Simply note the received signal in gEventSignals.
mDNSlocal void	NoteSignal(int signum)
	{
	sigaddset(&gEventSignals, signum);
	}

// Tell the event package to listen for signal and report it in mDNSPosixRunEventLoopOnce().
mStatus mDNSPosixListenForSignalInEventLoop(int signum)
	{
	struct sigaction	action;
	mStatus				err;

	mDNSPlatformMemZero(&action, sizeof action);		// more portable than member-wise assignment
	action.sa_handler = NoteSignal;
	err = sigaction(signum, &action, (struct sigaction*) NULL);
	
	sigaddset(&gEventSignalSet, signum);

	return err;
	}

// Tell the event package to stop listening for signal in mDNSPosixRunEventLoopOnce().
mStatus mDNSPosixIgnoreSignalInEventLoop(int signum)
	{
	struct sigaction	action;
	mStatus				err;

	mDNSPlatformMemZero(&action, sizeof action);		// more portable than member-wise assignment
	action.sa_handler = SIG_DFL;
	err = sigaction(signum, &action, (struct sigaction*) NULL);
	
	sigdelset(&gEventSignalSet, signum);

	return err;
	}

// Do a single pass through the attendent event sources and dispatch any found to their callbacks.
// Return as soon as internal timeout expires, or a signal we're listening for is received.
mStatus mDNSPosixRunEventLoopOnce(mDNS *m, const struct timeval *pTimeout, 
									sigset_t *pSignalsReceived, mDNSBool *pDataDispatched)
	{
	fd_set			listenFDs = gEventFDs;
	int				fdMax = 0, numReady;
	struct timeval	timeout = *pTimeout;
	
	// Include the sockets that are listening to the wire in our select() set
	mDNSPosixGetFDSet(m, &fdMax, &listenFDs, &timeout);	// timeout may get modified
	if (fdMax < gMaxFD)
		fdMax = gMaxFD;

	numReady = select(fdMax + 1, &listenFDs, (fd_set*) NULL, (fd_set*) NULL, &timeout);

	// If any data appeared, invoke its callback
	if (numReady > 0)
		{
		PosixEventSource	*iSource;

		(void) mDNSPosixProcessFDSet(m, &listenFDs);	// call this first to process wire data for clients

		for (iSource=(PosixEventSource*)gEventSources.Head; iSource; iSource = iSource->Next)
			{
			if (FD_ISSET(iSource->fd, &listenFDs))
				{
				iSource->Callback(iSource->fd, 0, iSource->Context);
				break;	// in case callback removed elements from gEventSources
				}
			}
		*pDataDispatched = mDNStrue;
		}
	else
		*pDataDispatched = mDNSfalse;

	(void) sigprocmask(SIG_BLOCK, &gEventSignalSet, (sigset_t*) NULL);
	*pSignalsReceived = gEventSignals;
	sigemptyset(&gEventSignals);
	(void) sigprocmask(SIG_UNBLOCK, &gEventSignalSet, (sigset_t*) NULL);

	return mStatus_NoError;
	}
