/* -*- 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;
#ifndef __ANDROID__
	gethostname((char *)(&namelabel->c[1]), MAX_DOMAIN_LABEL);
#else
	// use an appropriate default label rather than the linux default of 'localhost'
	strncpy(&namelabel->c[1], "Android", MAX_DOMAIN_LABEL);
#endif
	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;
	}
