13dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin/* -*- Mode: C; tab-width: 4 -*-
23dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin *
33dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin * Copyright (c) 2002-2004 Apple Computer, Inc. All rights reserved.
43dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin *
53dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin * Licensed under the Apache License, Version 2.0 (the "License");
63dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin * you may not use this file except in compliance with the License.
73dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin * You may obtain a copy of the License at
83dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin *
93dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin *     http://www.apache.org/licenses/LICENSE-2.0
103dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin *
113dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin * Unless required by applicable law or agreed to in writing, software
123dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin * distributed under the License is distributed on an "AS IS" BASIS,
133dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
143dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin * See the License for the specific language governing permissions and
153dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin * limitations under the License.
163dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
173dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	To Do:
183dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
193dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	- Get unicode name of machine for nice name instead of just the host name.
203dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	- Use the IPv6 Internet Connection Firewall API to allow IPv6 mDNS without manually changing the firewall.
213dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	- Get DNS server address(es) from Windows and provide them to the uDNS layer.
223dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	- Implement TCP support for truncated packets (only stubs now).
233dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
243dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin*/
253dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
263dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin#include	<stdarg.h>
273dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin#include	<stddef.h>
283dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin#include	<stdio.h>
293dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin#include	<stdlib.h>
303dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin#include	<crtdbg.h>
313dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin#include	<string.h>
323dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
333dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin#include	"CommonServices.h"
343dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin#include	"DebugServices.h"
353dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin#include	"Firewall.h"
363dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin#include	"RegNames.h"
373dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin#include	"Secret.h"
383dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin#include	<dns_sd.h>
393dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
403dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin#include	<Iphlpapi.h>
413dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin#include	<mswsock.h>
423dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin#include	<process.h>
433dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin#include	<ntsecapi.h>
443dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin#include	<lm.h>
453dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin#include	<winioctl.h>
463dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin#include	<ntddndis.h>        // This defines the IOCTL constants.
473dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
483dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin#include	"mDNSEmbeddedAPI.h"
493dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin#include	"GenLinkedList.h"
503dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin#include	"DNSCommon.h"
513dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin#include	"mDNSWin32.h"
523dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
533dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin#if 0
543dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin#pragma mark == Constants ==
553dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin#endif
563dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
573dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//===========================================================================================================================
583dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//	Constants
593dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//===========================================================================================================================
603dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
613dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin#define	DEBUG_NAME									"[mDNSWin32] "
623dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
633dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin#define	MDNS_WINDOWS_USE_IPV6_IF_ADDRS				1
643dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin#define	MDNS_WINDOWS_ENABLE_IPV4					1
653dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin#define	MDNS_WINDOWS_ENABLE_IPV6					1
663dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin#define	MDNS_FIX_IPHLPAPI_PREFIX_BUG				1
673dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin#define MDNS_SET_HINFO_STRINGS						0
683dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
693dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin#define	kMDNSDefaultName							"My Computer"
703dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
713dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin#define	kWinSockMajorMin							2
723dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin#define	kWinSockMinorMin							2
733dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
743dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin#define kRegistryMaxKeyLength						255
753dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin#define kRegistryMaxValueName						16383
763dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
773dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlinstatic GUID											kWSARecvMsgGUID = WSAID_WSARECVMSG;
783dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
793dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin#define kIPv6IfIndexBase							(10000000L)
803dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin#define SMBPortAsNumber								445
813dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin#define DEVICE_PREFIX								"\\\\.\\"
823dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
833dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin#if 0
843dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin#pragma mark == Prototypes ==
853dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin#endif
863dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
873dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//===========================================================================================================================
883dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//	Prototypes
893dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//===========================================================================================================================
903dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
913dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinmDNSlocal mStatus			SetupNiceName( mDNS * const inMDNS );
923dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinmDNSlocal mStatus			SetupHostName( mDNS * const inMDNS );
933dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinmDNSlocal mStatus			SetupName( mDNS * const inMDNS );
943dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinmDNSlocal mStatus			SetupInterface( mDNS * const inMDNS, const struct ifaddrs *inIFA, mDNSInterfaceData **outIFD );
953dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinmDNSlocal mStatus			TearDownInterface( mDNS * const inMDNS, mDNSInterfaceData *inIFD );
963dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinmDNSlocal void CALLBACK		FreeInterface( mDNSInterfaceData *inIFD );
973dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinmDNSlocal mStatus			SetupSocket( mDNS * const inMDNS, const struct sockaddr *inAddr, mDNSIPPort port, SocketRef *outSocketRef  );
983dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinmDNSlocal mStatus			SockAddrToMDNSAddr( const struct sockaddr * const inSA, mDNSAddr *outIP, mDNSIPPort *outPort );
993dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinmDNSlocal OSStatus			GetWindowsVersionString( char *inBuffer, size_t inBufferSize );
1003dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinmDNSlocal int				getifaddrs( struct ifaddrs **outAddrs );
1013dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinmDNSlocal void				freeifaddrs( struct ifaddrs *inAddrs );
1023dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
1033dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
1043dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
1053dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin// Platform Accessors
1063dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
1073dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin#ifdef	__cplusplus
1083dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	extern "C" {
1093dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin#endif
1103dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
1113dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlintypedef struct mDNSPlatformInterfaceInfo	mDNSPlatformInterfaceInfo;
1123dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlinstruct	mDNSPlatformInterfaceInfo
1133dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin{
1143dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	const char *		name;
1153dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	mDNSAddr			ip;
1163dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin};
1173dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
1183dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
1193dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinmDNSexport mStatus	mDNSPlatformInterfaceNameToID( mDNS * const inMDNS, const char *inName, mDNSInterfaceID *outID );
1203dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinmDNSexport mStatus	mDNSPlatformInterfaceIDToInfo( mDNS * const inMDNS, mDNSInterfaceID inID, mDNSPlatformInterfaceInfo *outInfo );
1213dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
1223dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin// Utilities
1233dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
1243dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin#if( MDNS_WINDOWS_USE_IPV6_IF_ADDRS )
1253dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	mDNSlocal int	getifaddrs_ipv6( struct ifaddrs **outAddrs );
1263dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin#endif
1273dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
1283dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinmDNSlocal int getifaddrs_ipv4( struct ifaddrs **outAddrs );
1293dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
1303dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
1313dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinmDNSlocal DWORD				GetPrimaryInterface();
1323dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinmDNSlocal mStatus			AddressToIndexAndMask( struct sockaddr * address, uint32_t * index, struct sockaddr * mask );
1333dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinmDNSlocal mDNSBool			CanReceiveUnicast( void );
1343dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinmDNSlocal mDNSBool			IsPointToPoint( IP_ADAPTER_UNICAST_ADDRESS * addr );
1353dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
1363dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinmDNSlocal mStatus			StringToAddress( mDNSAddr * ip, LPSTR string );
1373dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinmDNSlocal mStatus			RegQueryString( HKEY key, LPCSTR param, LPSTR * string, DWORD * stringLen, DWORD * enabled );
1383dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinmDNSlocal struct ifaddrs*	myGetIfAddrs(int refresh);
1393dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinmDNSlocal OSStatus			TCHARtoUTF8( const TCHAR *inString, char *inBuffer, size_t inBufferSize );
1403dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinmDNSlocal OSStatus			WindowsLatin1toUTF8( const char *inString, char *inBuffer, size_t inBufferSize );
1413dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinmDNSlocal void				TCPDidConnect( mDNS * const inMDNS, HANDLE event, void * context );
1423dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinmDNSlocal void				TCPCanRead( TCPSocket * sock );
1433dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinmDNSlocal mStatus			TCPBeginRecv( TCPSocket * sock );
1443dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinmDNSlocal void CALLBACK		TCPEndRecv( DWORD error, DWORD bytesTransferred, LPWSAOVERLAPPED overlapped, DWORD flags );
1453dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinmDNSlocal void				TCPCloseSocket( TCPSocket * socket );
1463dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinmDNSlocal void CALLBACK		TCPFreeSocket( TCPSocket *sock );
1473dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinmDNSlocal OSStatus			UDPBeginRecv( UDPSocket * socket );
1483dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinmDNSlocal void CALLBACK		UDPEndRecv( DWORD err, DWORD bytesTransferred, LPWSAOVERLAPPED overlapped, DWORD flags );
1493dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinmDNSlocal void				UDPCloseSocket( UDPSocket * sock );
1503dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinmDNSlocal void CALLBACK		UDPFreeSocket( UDPSocket * sock );
1513dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinmDNSlocal mStatus           SetupAddr(mDNSAddr *ip, const struct sockaddr *const sa);
1523dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinmDNSlocal void				GetDDNSFQDN( domainname *const fqdn );
1533dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin#ifdef UNICODE
1543dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinmDNSlocal void				GetDDNSDomains( DNameListElem ** domains, LPCWSTR lpSubKey );
1553dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin#else
1563dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinmDNSlocal void				GetDDNSDomains( DNameListElem ** domains, LPCSTR lpSubKey );
1573dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin#endif
1583dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinmDNSlocal void				SetDomainSecrets( mDNS * const inMDNS );
1593dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinmDNSlocal void				SetDomainSecret( mDNS * const m, const domainname * inDomain );
1603dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinmDNSlocal VOID CALLBACK		CheckFileSharesProc( LPVOID arg, DWORD dwTimerLowValue, DWORD dwTimerHighValue );
1613dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinmDNSlocal void				CheckFileShares( mDNS * const inMDNS );
1623dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinmDNSlocal void				SMBCallback(mDNS *const m, ServiceRecordSet *const srs, mStatus result);
1633dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinmDNSlocal mDNSu8			IsWOMPEnabledForAdapter( const char * adapterName );
1643dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinmDNSlocal void				DispatchUDPEvent( mDNS * const m, UDPSocket * sock );
1653dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinmDNSlocal void				DispatchTCPEvent( mDNS * const m, TCPSocket * sock );
1663dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
1673dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin#ifdef	__cplusplus
1683dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	}
1693dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin#endif
1703dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
1713dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin#if 0
1723dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin#pragma mark == Globals ==
1733dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin#endif
1743dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
1753dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//===========================================================================================================================
1763dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//	Globals
1773dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//===========================================================================================================================
1783dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
1793dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinmDNSlocal mDNS_PlatformSupport	gMDNSPlatformSupport;
1803dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinmDNSs32							mDNSPlatformOneSecond	= 0;
1813dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinmDNSlocal UDPSocket		*		gUDPSockets				= NULL;
1823dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinmDNSlocal int					gUDPNumSockets			= 0;
1833dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinmDNSlocal GenLinkedList			gUDPDispatchableSockets;
1843dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinmDNSlocal GenLinkedList			gTCPDispatchableSockets;
1853dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
1863dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin#if( MDNS_WINDOWS_USE_IPV6_IF_ADDRS )
1873dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
1883dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	typedef DWORD
1893dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		( WINAPI * GetAdaptersAddressesFunctionPtr )(
1903dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			ULONG 					inFamily,
1913dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			DWORD 					inFlags,
1923dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			PVOID 					inReserved,
1933dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			PIP_ADAPTER_ADDRESSES 	inAdapter,
1943dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			PULONG					outBufferSize );
1953dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
1963dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	mDNSlocal HMODULE								gIPHelperLibraryInstance			= NULL;
1973dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	mDNSlocal GetAdaptersAddressesFunctionPtr		gGetAdaptersAddressesFunctionPtr	= NULL;
1983dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
1993dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin#endif
2003dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
2013dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
2023dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin#ifndef HCRYPTPROV
2033dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin   typedef ULONG_PTR HCRYPTPROV;    // WinCrypt.h, line 249
2043dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin#endif
2053dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
2063dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
2073dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin#ifndef CRYPT_MACHINE_KEYSET
2083dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin#	define CRYPT_MACHINE_KEYSET    0x00000020
2093dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin#endif
2103dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
2113dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin#ifndef CRYPT_NEWKEYSET
2123dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin#	define CRYPT_NEWKEYSET         0x00000008
2133dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin#endif
2143dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
2153dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin#ifndef PROV_RSA_FULL
2163dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin#  define PROV_RSA_FULL 1
2173dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin#endif
2183dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
2193dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlintypedef BOOL (__stdcall *fnCryptGenRandom)( HCRYPTPROV, DWORD, BYTE* );
2203dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlintypedef BOOL (__stdcall *fnCryptAcquireContext)( HCRYPTPROV*, LPCTSTR, LPCTSTR, DWORD, DWORD);
2213dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlintypedef BOOL (__stdcall *fnCryptReleaseContext)(HCRYPTPROV, DWORD);
2223dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
2233dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlinstatic fnCryptAcquireContext g_lpCryptAcquireContext 	= NULL;
2243dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlinstatic fnCryptReleaseContext g_lpCryptReleaseContext 	= NULL;
2253dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlinstatic fnCryptGenRandom		 g_lpCryptGenRandom 		= NULL;
2263dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlinstatic HINSTANCE			 g_hAAPI32 					= NULL;
2273dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlinstatic HCRYPTPROV			 g_hProvider 				= ( ULONG_PTR ) NULL;
2283dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
2293dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
2303dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlintypedef DNSServiceErrorType ( DNSSD_API *DNSServiceRegisterFunc )
2313dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin    (
2323dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin    DNSServiceRef                       *sdRef,
2333dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin    DNSServiceFlags                     flags,
2343dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin    uint32_t                            interfaceIndex,
2353dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin    const char                          *name,         /* may be NULL */
2363dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin    const char                          *regtype,
2373dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin    const char                          *domain,       /* may be NULL */
2383dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin    const char                          *host,         /* may be NULL */
2393dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin    uint16_t                            port,
2403dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin    uint16_t                            txtLen,
2413dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin    const void                          *txtRecord,    /* may be NULL */
2423dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin    DNSServiceRegisterReply             callBack,      /* may be NULL */
2433dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin    void                                *context       /* may be NULL */
2443dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin    );
2453dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
2463dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
2473dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlintypedef void ( DNSSD_API *DNSServiceRefDeallocateFunc )( DNSServiceRef sdRef );
2483dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
2493dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinmDNSlocal HMODULE					gDNSSDLibrary				= NULL;
2503dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinmDNSlocal DNSServiceRegisterFunc	gDNSServiceRegister			= NULL;
2513dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinmDNSlocal DNSServiceRefDeallocateFunc gDNSServiceRefDeallocate	= NULL;
2523dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinmDNSlocal HANDLE					gSMBThread					= NULL;
2533dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinmDNSlocal HANDLE					gSMBThreadRegisterEvent		= NULL;
2543dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinmDNSlocal HANDLE					gSMBThreadDeregisterEvent	= NULL;
2553dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinmDNSlocal HANDLE					gSMBThreadStopEvent			= NULL;
2563dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinmDNSlocal HANDLE					gSMBThreadQuitEvent			= NULL;
2573dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
2583dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin#define	kSMBStopEvent				( WAIT_OBJECT_0 + 0 )
2593dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin#define	kSMBRegisterEvent			( WAIT_OBJECT_0 + 1 )
2603dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin#define kSMBDeregisterEvent			( WAIT_OBJECT_0 + 2 )
2613dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
2623dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
2633dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin#if 0
2643dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin#pragma mark -
2653dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin#pragma mark == Platform Support ==
2663dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin#endif
2673dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
2683dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//===========================================================================================================================
2693dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//	mDNSPlatformInit
2703dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//===========================================================================================================================
2713dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
2723dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinmDNSexport mStatus	mDNSPlatformInit( mDNS * const inMDNS )
2733dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin{
2743dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	mStatus		err;
2753dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	WSADATA		wsaData;
2763dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	int			supported;
2773dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	struct sockaddr_in	sa4;
2783dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	struct sockaddr_in6 sa6;
2793dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	int					sa4len;
2803dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	int					sa6len;
2813dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	DWORD				size;
2823dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	DWORD				val;
2833dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
2843dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	dlog( kDebugLevelTrace, DEBUG_NAME "platform init\n" );
2853dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
2863dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	// Initialize variables. If the PlatformSupport pointer is not null then just assume that a non-Apple client is
2873dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	// calling mDNS_Init and wants to provide its own storage for the platform-specific data so do not overwrite it.
2883dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
2893dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	mDNSPlatformMemZero( &gMDNSPlatformSupport, sizeof( gMDNSPlatformSupport ) );
2903dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	if( !inMDNS->p ) inMDNS->p				= &gMDNSPlatformSupport;
2913dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	inMDNS->p->mainThread					= OpenThread( THREAD_ALL_ACCESS, FALSE, GetCurrentThreadId() );
2923dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	require_action( inMDNS->p->mainThread, exit, err = mStatus_UnknownErr );
2933dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	inMDNS->p->checkFileSharesTimer = CreateWaitableTimer( NULL, FALSE, NULL );
2943dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	require_action( inMDNS->p->checkFileSharesTimer, exit, err = mStatus_UnknownErr );
2953dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	inMDNS->p->checkFileSharesTimeout		= 10;		// Retry time for CheckFileShares() in seconds
2963dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	mDNSPlatformOneSecond 					= 1000;		// Use milliseconds as the quantum of time
2973dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	InitLinkedList( &gTCPDispatchableSockets, offsetof( TCPSocket, nextDispatchable ) );
2983dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	InitLinkedList( &gUDPDispatchableSockets, offsetof( UDPSocket, nextDispatchable ) );
2993dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
3003dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	// Startup WinSock 2.2 or later.
3013dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
3023dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	err = WSAStartup( MAKEWORD( kWinSockMajorMin, kWinSockMinorMin ), &wsaData );
3033dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	require_noerr( err, exit );
3043dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
3053dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	supported = ( ( LOBYTE( wsaData.wVersion ) == kWinSockMajorMin ) && ( HIBYTE( wsaData.wVersion ) == kWinSockMinorMin ) );
3063dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	require_action( supported, exit, err = mStatus_UnsupportedErr );
3073dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
3083dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	inMDNS->CanReceiveUnicastOn5353 = CanReceiveUnicast();
3093dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
3103dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	// Setup the HINFO HW strings.
3113dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	//<rdar://problem/7245119> device-info should have model=Windows
3123dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
3133dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	strcpy_s( ( char* ) &inMDNS->HIHardware.c[ 1 ], sizeof( inMDNS->HIHardware.c ) - 2, "Windows" );
3143dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	inMDNS->HIHardware.c[ 0 ] = ( mDNSu8 ) mDNSPlatformStrLen( &inMDNS->HIHardware.c[ 1 ] );
3153dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	dlog( kDebugLevelInfo, DEBUG_NAME "HIHardware: %#s\n", inMDNS->HIHardware.c );
3163dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
3173dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	// Setup the HINFO SW strings.
3183dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin#if ( MDNS_SET_HINFO_STRINGS )
3193dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	mDNS_snprintf( (char *) &inMDNS->HISoftware.c[ 1 ], sizeof( inMDNS->HISoftware.c ) - 2,
3203dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		"mDNSResponder (%s %s)", __DATE__, __TIME__ );
3213dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	inMDNS->HISoftware.c[ 0 ] = (mDNSu8) mDNSPlatformStrLen( &inMDNS->HISoftware.c[ 1 ] );
3223dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	dlog( kDebugLevelInfo, DEBUG_NAME "HISoftware: %#s\n", inMDNS->HISoftware.c );
3233dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin#endif
3243dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
3253dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	// Set the thread global overlapped flag
3263dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
3273dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	val = 0;
3283dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	err = setsockopt( INVALID_SOCKET, SOL_SOCKET, SO_OPENTYPE, ( char* ) &val, sizeof( val ) );
3293dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	err = translate_errno( err != SOCKET_ERROR, WSAGetLastError(), kUnknownErr );
3303dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	require_noerr( err, exit );
3313dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
3323dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	// Set up the IPv4 unicast socket
3333dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
3343dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	inMDNS->p->unicastSock4.fd			= INVALID_SOCKET;
3353dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	inMDNS->p->unicastSock4.recvMsgPtr	= NULL;
3363dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	inMDNS->p->unicastSock4.ifd			= NULL;
3373dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	inMDNS->p->unicastSock4.overlapped.pending = FALSE;
3383dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	inMDNS->p->unicastSock4.next		= NULL;
3393dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	inMDNS->p->unicastSock4.m			= inMDNS;
3403dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
3413dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin#if ( MDNS_WINDOWS_ENABLE_IPV4 )
3423dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
3433dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	sa4.sin_family		= AF_INET;
3443dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	sa4.sin_addr.s_addr = INADDR_ANY;
3453dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	err = SetupSocket( inMDNS, (const struct sockaddr*) &sa4, zeroIPPort, &inMDNS->p->unicastSock4.fd );
3463dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	check_noerr( err );
3473dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	sa4len = sizeof( sa4 );
3483dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	err = getsockname( inMDNS->p->unicastSock4.fd, (struct sockaddr*) &sa4, &sa4len );
3493dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	require_noerr( err, exit );
3503dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	inMDNS->p->unicastSock4.port.NotAnInteger = sa4.sin_port;
3513dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	inMDNS->UnicastPort4 = inMDNS->p->unicastSock4.port;
3523dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	err = WSAIoctl( inMDNS->p->unicastSock4.fd, SIO_GET_EXTENSION_FUNCTION_POINTER, &kWSARecvMsgGUID, sizeof( kWSARecvMsgGUID ), &inMDNS->p->unicastSock4.recvMsgPtr, sizeof( inMDNS->p->unicastSock4.recvMsgPtr ), &size, NULL, NULL );
3533dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
3543dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	if ( err )
3553dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	{
3563dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		inMDNS->p->unicastSock4.recvMsgPtr = NULL;
3573dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	}
3583dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
3593dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	err = UDPBeginRecv( &inMDNS->p->unicastSock4 );
3603dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	require_noerr( err, exit );
3613dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
3623dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin#endif
3633dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
3643dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	// Set up the IPv6 unicast socket
3653dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
3663dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	inMDNS->p->unicastSock6.fd			= INVALID_SOCKET;
3673dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	inMDNS->p->unicastSock6.recvMsgPtr	= NULL;
3683dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	inMDNS->p->unicastSock6.ifd			= NULL;
3693dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	inMDNS->p->unicastSock6.overlapped.pending = FALSE;
3703dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	inMDNS->p->unicastSock6.next		= NULL;
3713dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	inMDNS->p->unicastSock6.m			= inMDNS;
3723dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
3733dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin#if ( MDNS_WINDOWS_ENABLE_IPV6 )
3743dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
3753dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	sa6.sin6_family		= AF_INET6;
3763dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	sa6.sin6_addr		= in6addr_any;
3773dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	sa6.sin6_scope_id	= 0;
3783dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
3793dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	// This call will fail if the machine hasn't installed IPv6.  In that case,
3803dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	// the error will be WSAEAFNOSUPPORT.
3813dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
3823dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	err = SetupSocket( inMDNS, (const struct sockaddr*) &sa6, zeroIPPort, &inMDNS->p->unicastSock6.fd );
3833dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	require_action( !err || ( err == WSAEAFNOSUPPORT ), exit, err = (mStatus) WSAGetLastError() );
3843dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	err = kNoErr;
3853dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
3863dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	// If we weren't able to create the socket (because IPv6 hasn't been installed) don't do this
3873dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
3883dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	if ( inMDNS->p->unicastSock6.fd != INVALID_SOCKET )
3893dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	{
3903dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		sa6len = sizeof( sa6 );
3913dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		err = getsockname( inMDNS->p->unicastSock6.fd, (struct sockaddr*) &sa6, &sa6len );
3923dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		require_noerr( err, exit );
3933dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		inMDNS->p->unicastSock6.port.NotAnInteger = sa6.sin6_port;
3943dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		inMDNS->UnicastPort6 = inMDNS->p->unicastSock6.port;
3953dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
3963dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		err = WSAIoctl( inMDNS->p->unicastSock6.fd, SIO_GET_EXTENSION_FUNCTION_POINTER, &kWSARecvMsgGUID, sizeof( kWSARecvMsgGUID ), &inMDNS->p->unicastSock6.recvMsgPtr, sizeof( inMDNS->p->unicastSock6.recvMsgPtr ), &size, NULL, NULL );
3973dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
3983dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		if ( err != 0 )
3993dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		{
4003dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			inMDNS->p->unicastSock6.recvMsgPtr = NULL;
4013dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		}
4023dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
4033dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		err = UDPBeginRecv( &inMDNS->p->unicastSock6 );
4043dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		require_noerr( err, exit );
4053dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	}
4063dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
4073dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin#endif
4083dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
4093dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	// Notify core of domain secret keys
4103dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
4113dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	SetDomainSecrets( inMDNS );
4123dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
4133dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	// Success!
4143dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
4153dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	mDNSCoreInitComplete( inMDNS, err );
4163dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
4173dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
4183dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlinexit:
4193dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
4203dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	if ( err )
4213dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	{
4223dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		mDNSPlatformClose( inMDNS );
4233dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	}
4243dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
4253dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	dlog( kDebugLevelTrace, DEBUG_NAME "platform init done (err=%d %m)\n", err, err );
4263dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	return( err );
4273dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin}
4283dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
4293dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//===========================================================================================================================
4303dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//	mDNSPlatformClose
4313dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//===========================================================================================================================
4323dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
4333dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinmDNSexport void	mDNSPlatformClose( mDNS * const inMDNS )
4343dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin{
4353dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	mStatus		err;
4363dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
4373dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	dlog( kDebugLevelTrace, DEBUG_NAME "platform close\n" );
4383dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	check( inMDNS );
4393dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
4403dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	if ( gSMBThread != NULL )
4413dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	{
4423dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		dlog( kDebugLevelTrace, DEBUG_NAME "tearing down smb registration thread\n" );
4433dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		SetEvent( gSMBThreadStopEvent );
4443dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
4453dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		if ( WaitForSingleObject( gSMBThreadQuitEvent, 5 * 1000 ) == WAIT_OBJECT_0 )
4463dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		{
4473dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			if ( gSMBThreadQuitEvent )
4483dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			{
4493dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin				CloseHandle( gSMBThreadQuitEvent );
4503dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin				gSMBThreadQuitEvent = NULL;
4513dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			}
4523dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
4533dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			if ( gSMBThreadStopEvent )
4543dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			{
4553dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin				CloseHandle( gSMBThreadStopEvent );
4563dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin				gSMBThreadStopEvent = NULL;
4573dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			}
4583dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
4593dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			if ( gSMBThreadDeregisterEvent )
4603dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			{
4613dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin				CloseHandle( gSMBThreadDeregisterEvent );
4623dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin				gSMBThreadDeregisterEvent = NULL;
4633dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			}
4643dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
4653dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			if ( gSMBThreadRegisterEvent )
4663dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			{
4673dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin				CloseHandle( gSMBThreadRegisterEvent );
4683dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin				gSMBThreadRegisterEvent = NULL;
4693dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			}
4703dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
4713dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			if ( gDNSSDLibrary )
4723dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			{
4733dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin				FreeLibrary( gDNSSDLibrary );
4743dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin				gDNSSDLibrary = NULL;
4753dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			}
4763dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		}
4773dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		else
4783dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		{
4793dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			LogMsg( "Unable to stop SMBThread" );
4803dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		}
4813dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
4823dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		inMDNS->p->smbFileSharing = mDNSfalse;
4833dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		inMDNS->p->smbPrintSharing = mDNSfalse;
4843dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	}
4853dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
4863dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	// Tear everything down in reverse order to how it was set up.
4873dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
4883dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	err = TearDownInterfaceList( inMDNS );
4893dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	check_noerr( err );
4903dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	check( !inMDNS->p->inactiveInterfaceList );
4913dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
4923dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin#if ( MDNS_WINDOWS_ENABLE_IPV4 )
4933dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
4943dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	UDPCloseSocket( &inMDNS->p->unicastSock4 );
4953dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
4963dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin#endif
4973dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
4983dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin#if ( MDNS_WINDOWS_ENABLE_IPV6 )
4993dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
5003dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	UDPCloseSocket( &inMDNS->p->unicastSock6 );
5013dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
5023dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin#endif
5033dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
5043dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	// Free the DLL needed for IPv6 support.
5053dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
5063dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin#if( MDNS_WINDOWS_USE_IPV6_IF_ADDRS )
5073dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	if( gIPHelperLibraryInstance )
5083dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	{
5093dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		gGetAdaptersAddressesFunctionPtr = NULL;
5103dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
5113dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		FreeLibrary( gIPHelperLibraryInstance );
5123dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		gIPHelperLibraryInstance = NULL;
5133dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	}
5143dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin#endif
5153dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
5163dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	if ( g_hAAPI32 )
5173dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	{
5183dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		// Release any resources
5193dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
5203dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		if ( g_hProvider && g_lpCryptReleaseContext )
5213dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		{
5223dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			( g_lpCryptReleaseContext )( g_hProvider, 0 );
5233dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		}
5243dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
5253dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		// Free the AdvApi32.dll
5263dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
5273dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		FreeLibrary( g_hAAPI32 );
5283dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
5293dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		// And reset all the data
5303dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
5313dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		g_lpCryptAcquireContext = NULL;
5323dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		g_lpCryptReleaseContext = NULL;
5333dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		g_lpCryptGenRandom 		= NULL;
5343dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		g_hProvider 			= ( ULONG_PTR ) NULL;
5353dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		g_hAAPI32				= NULL;
5363dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	}
5373dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
5383dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	// Clear out the APC queue
5393dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
5403dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	while ( SleepEx( 0, TRUE ) == WAIT_IO_COMPLETION )
5413dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	{
5423dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		DispatchSocketEvents( inMDNS );
5433dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	}
5443dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
5453dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	WSACleanup();
5463dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
5473dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	dlog( kDebugLevelTrace, DEBUG_NAME "platform close done\n" );
5483dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin}
5493dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
5503dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
5513dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//===========================================================================================================================
5523dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//	mDNSPlatformLock
5533dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//===========================================================================================================================
5543dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
5553dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinmDNSexport void	mDNSPlatformLock( const mDNS * const inMDNS )
5563dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin{
5573dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	( void ) inMDNS;
5583dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin}
5593dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
5603dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//===========================================================================================================================
5613dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//	mDNSPlatformUnlock
5623dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//===========================================================================================================================
5633dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
5643dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinmDNSexport void	mDNSPlatformUnlock( const mDNS * const inMDNS )
5653dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin{
5663dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	( void ) inMDNS;
5673dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin}
5683dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
5693dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//===========================================================================================================================
5703dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//	mDNSPlatformStrCopy
5713dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//===========================================================================================================================
5723dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
5733dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinmDNSexport void	mDNSPlatformStrCopy( void *inDst, const void *inSrc )
5743dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin{
5753dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	check( inSrc );
5763dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	check( inDst );
5773dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
5783dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	strcpy( (char *) inDst, (const char*) inSrc );
5793dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin}
5803dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
5813dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//===========================================================================================================================
5823dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//	mDNSPlatformStrLCopy
5833dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//===========================================================================================================================
5843dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
5853dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinmDNSexport mDNSu32 mDNSPlatformStrLCopy(void *inDst, const void *inSrc, mDNSu32 inSize)
5863dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin{
5873dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	const char *		src = (const char *) inSrc;
5883dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
5893dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	if( inSize > 0 )
5903dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	{
5913dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		size_t		n;
5923dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		char *		dst = (char *) inDst;
5933dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
5943dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		for( n = inSize - 1; n > 0; --n )
5953dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		{
5963dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			if( ( *dst++ = *src++ ) == '\0' )
5973dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			{
5983dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin				// Null terminator encountered, so exit.
5993dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin				goto exit;
6003dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			}
6013dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		}
6023dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		*dst = '\0';
6033dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	}
6043dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
6053dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	while( *src++ != '\0' )
6063dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	{
6073dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		// Stop at null terminator.
6083dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	}
6093dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
6103dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlinexit:
6113dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	return( (mDNSu32)( src - (const char *) inSrc ) - 1 );
6123dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin}
6133dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
6143dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//===========================================================================================================================
6153dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//	mDNSPlatformStrLen
6163dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//===========================================================================================================================
6173dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
6183dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinmDNSexport mDNSu32	mDNSPlatformStrLen( const void *inSrc )
6193dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin{
6203dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	check( inSrc );
6213dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
6223dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	return( (mDNSu32) strlen( (const char *) inSrc ) );
6233dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin}
6243dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
6253dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//===========================================================================================================================
6263dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//	mDNSPlatformMemCopy
6273dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//===========================================================================================================================
6283dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
6293dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinmDNSexport void	mDNSPlatformMemCopy( void *inDst, const void *inSrc, mDNSu32 inSize )
6303dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin{
6313dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	check( inSrc );
6323dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	check( inDst );
6333dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
6343dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	memcpy( inDst, inSrc, inSize );
6353dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin}
6363dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
6373dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//===========================================================================================================================
6383dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//	mDNSPlatformMemSame
6393dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//===========================================================================================================================
6403dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
6413dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinmDNSexport mDNSBool	mDNSPlatformMemSame( const void *inDst, const void *inSrc, mDNSu32 inSize )
6423dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin{
6433dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	check( inSrc );
6443dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	check( inDst );
6453dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
6463dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	return( (mDNSBool)( memcmp( inSrc, inDst, inSize ) == 0 ) );
6473dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin}
6483dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
6493dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//===========================================================================================================================
6503dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//	mDNSPlatformMemZero
6513dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//===========================================================================================================================
6523dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
6533dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinmDNSexport void	mDNSPlatformMemZero( void *inDst, mDNSu32 inSize )
6543dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin{
6553dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	check( inDst );
6563dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
6573dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	memset( inDst, 0, inSize );
6583dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin}
6593dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
6603dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//===========================================================================================================================
6613dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//	mDNSPlatformMemAllocate
6623dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//===========================================================================================================================
6633dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
6643dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinmDNSexport void *	mDNSPlatformMemAllocate( mDNSu32 inSize )
6653dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin{
6663dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	void *		mem;
6673dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
6683dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	check( inSize > 0 );
6693dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
6703dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	mem = malloc( inSize );
6713dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	check( mem );
6723dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
6733dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	return( mem );
6743dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin}
6753dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
6763dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//===========================================================================================================================
6773dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//	mDNSPlatformMemFree
6783dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//===========================================================================================================================
6793dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
6803dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinmDNSexport void	mDNSPlatformMemFree( void *inMem )
6813dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin{
6823dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	check( inMem );
6833dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
6843dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	free( inMem );
6853dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin}
6863dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
6873dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//===========================================================================================================================
6883dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//	mDNSPlatformRandomNumber
6893dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//===========================================================================================================================
6903dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
6913dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinmDNSexport mDNSu32 mDNSPlatformRandomNumber(void)
6923dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin{
6933dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	mDNSu32		randomNumber = 0;
6943dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	BOOL		bResult;
6953dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	OSStatus	err = 0;
6963dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
6973dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	if ( !g_hAAPI32 )
6983dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	{
6993dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		g_hAAPI32 = LoadLibrary( TEXT("AdvAPI32.dll") );
7003dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		err = translate_errno( g_hAAPI32 != NULL, GetLastError(), mStatus_UnknownErr );
7013dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		require_noerr( err, exit );
7023dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	}
7033dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
7043dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	// Function Pointer: CryptAcquireContext
7053dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
7063dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	if ( !g_lpCryptAcquireContext )
7073dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	{
7083dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		g_lpCryptAcquireContext = ( fnCryptAcquireContext )
7093dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin#ifdef UNICODE
7103dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			( GetProcAddress( g_hAAPI32, "CryptAcquireContextW" ) );
7113dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin#else
7123dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			( GetProcAddress( g_hAAPI32, "CryptAcquireContextA" ) );
7133dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin#endif
7143dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		err = translate_errno( g_lpCryptAcquireContext != NULL, GetLastError(), mStatus_UnknownErr );
7153dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		require_noerr( err, exit );
7163dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	}
7173dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
7183dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	// Function Pointer: CryptReleaseContext
7193dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
7203dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	if ( !g_lpCryptReleaseContext )
7213dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	{
7223dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		g_lpCryptReleaseContext = ( fnCryptReleaseContext )
7233dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin         ( GetProcAddress( g_hAAPI32, "CryptReleaseContext" ) );
7243dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		err = translate_errno( g_lpCryptReleaseContext != NULL, GetLastError(), mStatus_UnknownErr );
7253dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		require_noerr( err, exit );
7263dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	}
7273dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
7283dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	// Function Pointer: CryptGenRandom
7293dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
7303dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	if ( !g_lpCryptGenRandom )
7313dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	{
7323dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		g_lpCryptGenRandom = ( fnCryptGenRandom )
7333dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin          ( GetProcAddress( g_hAAPI32, "CryptGenRandom" ) );
7343dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		err = translate_errno( g_lpCryptGenRandom != NULL, GetLastError(), mStatus_UnknownErr );
7353dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		require_noerr( err, exit );
7363dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	}
7373dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
7383dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	// Setup
7393dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
7403dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	if ( !g_hProvider )
7413dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	{
7423dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		bResult = (*g_lpCryptAcquireContext)( &g_hProvider, NULL, NULL, PROV_RSA_FULL, CRYPT_MACHINE_KEYSET );
7433dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
7443dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		if ( !bResult )
7453dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		{
7463dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			bResult =  ( *g_lpCryptAcquireContext)( &g_hProvider, NULL, NULL, PROV_RSA_FULL, CRYPT_MACHINE_KEYSET | CRYPT_NEWKEYSET );
7473dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			err = translate_errno( bResult, GetLastError(), mStatus_UnknownErr );
7483dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			require_noerr( err, exit );
7493dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		}
7503dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	}
7513dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
7523dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	bResult = (*g_lpCryptGenRandom)( g_hProvider, sizeof( randomNumber ), ( BYTE* ) &randomNumber );
7533dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	err = translate_errno( bResult, GetLastError(), mStatus_UnknownErr );
7543dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	require_noerr( err, exit );
7553dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
7563dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlinexit:
7573dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
7583dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	if ( err )
7593dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	{
7603dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		randomNumber = rand();
7613dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	}
7623dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
7633dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	return randomNumber;
7643dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin}
7653dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
7663dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//===========================================================================================================================
7673dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//	mDNSPlatformTimeInit
7683dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//===========================================================================================================================
7693dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
7703dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinmDNSexport mStatus	mDNSPlatformTimeInit( void )
7713dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin{
7723dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	// No special setup is required on Windows -- we just use GetTickCount().
7733dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	return( mStatus_NoError );
7743dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin}
7753dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
7763dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//===========================================================================================================================
7773dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//	mDNSPlatformRawTime
7783dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//===========================================================================================================================
7793dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
7803dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinmDNSexport mDNSs32	mDNSPlatformRawTime( void )
7813dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin{
7823dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	return( (mDNSs32) GetTickCount() );
7833dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin}
7843dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
7853dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//===========================================================================================================================
7863dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//	mDNSPlatformUTC
7873dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//===========================================================================================================================
7883dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
7893dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinmDNSexport mDNSs32	mDNSPlatformUTC( void )
7903dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin{
7913dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	return ( mDNSs32 ) time( NULL );
7923dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin}
7933dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
7943dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//===========================================================================================================================
7953dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//	mDNSPlatformInterfaceNameToID
7963dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//===========================================================================================================================
7973dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
7983dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinmDNSexport mStatus	mDNSPlatformInterfaceNameToID( mDNS * const inMDNS, const char *inName, mDNSInterfaceID *outID )
7993dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin{
8003dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	mStatus					err;
8013dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	mDNSInterfaceData *		ifd;
8023dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
8033dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	check( inMDNS );
8043dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	check( inMDNS->p );
8053dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	check( inName );
8063dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
8073dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	// Search for an interface with the specified name,
8083dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
8093dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	for( ifd = inMDNS->p->interfaceList; ifd; ifd = ifd->next )
8103dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	{
8113dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		if( strcmp( ifd->name, inName ) == 0 )
8123dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		{
8133dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			break;
8143dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		}
8153dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	}
8163dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	require_action_quiet( ifd, exit, err = mStatus_NoSuchNameErr );
8173dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
8183dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	// Success!
8193dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
8203dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	if( outID )
8213dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	{
8223dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		*outID = (mDNSInterfaceID) ifd;
8233dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	}
8243dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	err = mStatus_NoError;
8253dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
8263dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlinexit:
8273dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	return( err );
8283dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin}
8293dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
8303dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//===========================================================================================================================
8313dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//	mDNSPlatformInterfaceIDToInfo
8323dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//===========================================================================================================================
8333dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
8343dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinmDNSexport mStatus	mDNSPlatformInterfaceIDToInfo( mDNS * const inMDNS, mDNSInterfaceID inID, mDNSPlatformInterfaceInfo *outInfo )
8353dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin{
8363dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	mStatus					err;
8373dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	mDNSInterfaceData *		ifd;
8383dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
8393dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	check( inMDNS );
8403dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	check( inID );
8413dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	check( outInfo );
8423dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
8433dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	// Search for an interface with the specified ID,
8443dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
8453dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	for( ifd = inMDNS->p->interfaceList; ifd; ifd = ifd->next )
8463dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	{
8473dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		if( ifd == (mDNSInterfaceData *) inID )
8483dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		{
8493dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			break;
8503dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		}
8513dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	}
8523dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	require_action_quiet( ifd, exit, err = mStatus_NoSuchNameErr );
8533dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
8543dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	// Success!
8553dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
8563dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	outInfo->name 	= ifd->name;
8573dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	outInfo->ip 	= ifd->interfaceInfo.ip;
8583dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	err 			= mStatus_NoError;
8593dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
8603dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlinexit:
8613dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	return( err );
8623dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin}
8633dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
8643dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//===========================================================================================================================
8653dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//	mDNSPlatformInterfaceIDfromInterfaceIndex
8663dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//===========================================================================================================================
8673dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
8683dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinmDNSexport mDNSInterfaceID	mDNSPlatformInterfaceIDfromInterfaceIndex( mDNS * const inMDNS, mDNSu32 inIndex )
8693dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin{
8703dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	mDNSInterfaceID		id;
8713dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
8723dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	id = mDNSNULL;
8733dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	if( inIndex == kDNSServiceInterfaceIndexLocalOnly )
8743dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	{
8753dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		id = mDNSInterface_LocalOnly;
8763dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	}
8773dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	/* uncomment if Windows ever supports P2P
8783dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	else if( inIndex == kDNSServiceInterfaceIndexP2P )
8793dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	{
8803dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		id = mDNSInterface_P2P;
8813dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	}
8823dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	*/
8833dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	else if( inIndex != 0 )
8843dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	{
8853dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		mDNSInterfaceData *		ifd;
8863dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
8873dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		for( ifd = inMDNS->p->interfaceList; ifd; ifd = ifd->next )
8883dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		{
8893dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			if( ( ifd->scopeID == inIndex ) && ifd->interfaceInfo.InterfaceActive )
8903dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			{
8913dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin				id = ifd->interfaceInfo.InterfaceID;
8923dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin				break;
8933dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			}
8943dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		}
8953dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		check( ifd );
8963dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	}
8973dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	return( id );
8983dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin}
8993dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
9003dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//===========================================================================================================================
9013dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//	mDNSPlatformInterfaceIndexfromInterfaceID
9023dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//===========================================================================================================================
9033dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
9043dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinmDNSexport mDNSu32	mDNSPlatformInterfaceIndexfromInterfaceID( mDNS * const inMDNS, mDNSInterfaceID inID, mDNSBool suppressNetworkChange )
9053dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin{
9063dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	mDNSu32		index;
9073dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	(void) suppressNetworkChange; // Unused
9083dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
9093dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	index = 0;
9103dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	if( inID == mDNSInterface_LocalOnly )
9113dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	{
9123dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		index = (mDNSu32) kDNSServiceInterfaceIndexLocalOnly;
9133dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	}
9143dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	/* uncomment if Windows ever supports P2P
9153dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	else if( inID == mDNSInterface_P2P )
9163dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	{
9173dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		index = (mDNSu32) kDNSServiceInterfaceIndexP2P;
9183dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	}
9193dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	*/
9203dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	else if( inID )
9213dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	{
9223dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		mDNSInterfaceData *		ifd;
9233dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
9243dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		// Search active interfaces.
9253dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		for( ifd = inMDNS->p->interfaceList; ifd; ifd = ifd->next )
9263dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		{
9273dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			if( (mDNSInterfaceID) ifd == inID )
9283dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			{
9293dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin				index = ifd->scopeID;
9303dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin				break;
9313dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			}
9323dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		}
9333dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
9343dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		// Search inactive interfaces too so remove events for inactive interfaces report the old interface index.
9353dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
9363dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		if( !ifd )
9373dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		{
9383dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			for( ifd = inMDNS->p->inactiveInterfaceList; ifd; ifd = ifd->next )
9393dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			{
9403dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin				if( (mDNSInterfaceID) ifd == inID )
9413dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin				{
9423dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin					index = ifd->scopeID;
9433dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin					break;
9443dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin				}
9453dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			}
9463dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		}
9473dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		check( ifd );
9483dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	}
9493dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	return( index );
9503dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin}
9513dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
9523dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
9533dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//===========================================================================================================================
9543dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//	mDNSPlatformTCPSocket
9553dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//===========================================================================================================================
9563dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
9573dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinTCPSocket *
9583dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinmDNSPlatformTCPSocket
9593dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	(
9603dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	mDNS			* const m,
9613dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	TCPSocketFlags		flags,
9623dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	mDNSIPPort			*	port
9633dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	)
9643dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin{
9653dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	TCPSocket *		sock    = NULL;
9663dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	u_long				on		= 1;  // "on" for setsockopt
9673dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	struct sockaddr_in	saddr;
9683dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	int					len;
9693dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	mStatus				err		= mStatus_NoError;
9703dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
9713dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	DEBUG_UNUSED( m );
9723dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
9733dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	require_action( flags == 0, exit, err = mStatus_UnsupportedErr );
9743dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
9753dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	// Setup connection data object
9763dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
9773dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	sock = (TCPSocket *) malloc( sizeof( TCPSocket ) );
9783dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	require_action( sock, exit, err = mStatus_NoMemoryErr );
9793dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	mDNSPlatformMemZero( sock, sizeof( TCPSocket ) );
9803dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	sock->fd		= INVALID_SOCKET;
9813dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	sock->flags		= flags;
9823dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	sock->m			= m;
9833dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
9843dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	mDNSPlatformMemZero(&saddr, sizeof(saddr));
9853dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	saddr.sin_family		= AF_INET;
9863dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	saddr.sin_addr.s_addr	= htonl( INADDR_ANY );
9873dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	saddr.sin_port			= port->NotAnInteger;
9883dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
9893dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	// Create the socket
9903dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
9913dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	sock->fd = socket(AF_INET, SOCK_STREAM, 0);
9923dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	err = translate_errno( sock->fd != INVALID_SOCKET, WSAGetLastError(), mStatus_UnknownErr );
9933dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	require_noerr( err, exit );
9943dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
9953dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	// bind
9963dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
9973dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	err = bind( sock->fd, ( struct sockaddr* ) &saddr, sizeof( saddr )  );
9983dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	err = translate_errno( err == 0, WSAGetLastError(), mStatus_UnknownErr );
9993dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	require_noerr( err, exit );
10003dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
10013dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	// Set it to be non-blocking
10023dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
10033dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	err = ioctlsocket( sock->fd, FIONBIO, &on );
10043dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	err = translate_errno( err == 0, WSAGetLastError(), mStatus_UnknownErr );
10053dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	require_noerr( err, exit );
10063dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
10073dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	// Get port number
10083dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
10093dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	mDNSPlatformMemZero( &saddr, sizeof( saddr ) );
10103dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	len = sizeof( saddr );
10113dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
10123dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	err = getsockname( sock->fd, ( struct sockaddr* ) &saddr, &len );
10133dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	err = translate_errno( err == 0, WSAGetLastError(), mStatus_UnknownErr );
10143dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	require_noerr( err, exit );
10153dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
10163dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	port->NotAnInteger = saddr.sin_port;
10173dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
10183dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlinexit:
10193dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
10203dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	if ( err && sock )
10213dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	{
10223dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		TCPFreeSocket( sock );
10233dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		sock = mDNSNULL;
10243dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	}
10253dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
10263dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	return sock;
10273dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin}
10283dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
10293dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//===========================================================================================================================
10303dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//	mDNSPlatformTCPConnect
10313dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//===========================================================================================================================
10323dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
10333dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinmStatus
10343dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinmDNSPlatformTCPConnect
10353dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	(
10363dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	TCPSocket			*	sock,
10373dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	const mDNSAddr		*	inDstIP,
10383dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	mDNSOpaque16 			inDstPort,
10393dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	domainname          *   hostname,
10403dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	mDNSInterfaceID			inInterfaceID,
10413dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	TCPConnectionCallback	inCallback,
10423dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	void *					inContext
10433dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	)
10443dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin{
10453dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	struct sockaddr_in	saddr;
10463dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	mStatus				err		= mStatus_NoError;
10473dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
10483dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	DEBUG_UNUSED( inInterfaceID );
10493dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	( void ) hostname;
10503dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
10513dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	if ( inDstIP->type != mDNSAddrType_IPv4 )
10523dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	{
10533dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		LogMsg("ERROR: mDNSPlatformTCPConnect - attempt to connect to an IPv6 address: operation not supported");
10543dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		return mStatus_UnknownErr;
10553dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	}
10563dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
10573dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	// Setup connection data object
10583dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
10593dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	sock->readEventHandler	= TCPCanRead;
10603dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	sock->userCallback		= inCallback;
10613dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	sock->userContext		= inContext;
10623dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
10633dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	mDNSPlatformMemZero(&saddr, sizeof(saddr));
10643dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	saddr.sin_family	= AF_INET;
10653dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	saddr.sin_port		= inDstPort.NotAnInteger;
10663dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	memcpy(&saddr.sin_addr, &inDstIP->ip.v4.NotAnInteger, sizeof(saddr.sin_addr));
10673dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
10683dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	// Try and do connect
10693dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
10703dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	err = connect( sock->fd, ( struct sockaddr* ) &saddr, sizeof( saddr ) );
10713dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	require_action( !err || ( WSAGetLastError() == WSAEWOULDBLOCK ), exit, err = mStatus_ConnFailed );
10723dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	sock->connected	= !err ? TRUE : FALSE;
10733dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
10743dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	if ( sock->connected )
10753dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	{
10763dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		err = TCPAddSocket( sock->m, sock );
10773dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		require_noerr( err, exit );
10783dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	}
10793dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	else
10803dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	{
10813dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		require_action( sock->m->p->registerWaitableEventFunc != NULL, exit, err = mStatus_ConnFailed );
10823dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
10833dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		sock->connectEvent	= CreateEvent( NULL, FALSE, FALSE, NULL );
10843dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		err = translate_errno( sock->connectEvent, GetLastError(), mStatus_UnknownErr );
10853dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		require_noerr( err, exit );
10863dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
10873dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		err = WSAEventSelect( sock->fd, sock->connectEvent, FD_CONNECT );
10883dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		require_noerr( err, exit );
10893dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
10903dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		err = sock->m->p->registerWaitableEventFunc( sock->m, sock->connectEvent, sock, TCPDidConnect );
10913dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		require_noerr( err, exit );
10923dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	}
10933dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
10943dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlinexit:
10953dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
10963dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	if ( !err )
10973dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	{
10983dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		err = sock->connected ? mStatus_ConnEstablished : mStatus_ConnPending;
10993dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	}
11003dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
11013dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	return err;
11023dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin}
11033dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
11043dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//===========================================================================================================================
11053dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//	mDNSPlatformTCPAccept
11063dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//===========================================================================================================================
11073dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
11083dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinmDNSexport
11093dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinmDNSexport TCPSocket *mDNSPlatformTCPAccept( TCPSocketFlags flags, int fd )
11103dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	{
11113dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	TCPSocket	*	sock = NULL;
11123dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	mStatus							err = mStatus_NoError;
11133dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
11143dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	require_action( !flags, exit, err = mStatus_UnsupportedErr );
11153dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
11163dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	sock = malloc( sizeof( TCPSocket ) );
11173dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	require_action( sock, exit, err = mStatus_NoMemoryErr );
11183dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
11193dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	mDNSPlatformMemZero( sock, sizeof( *sock ) );
11203dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
11213dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	sock->fd	= fd;
11223dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	sock->flags = flags;
11233dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
11243dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlinexit:
11253dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
11263dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	if ( err && sock )
11273dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	{
11283dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		free( sock );
11293dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		sock = NULL;
11303dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	}
11313dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
11323dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	return sock;
11333dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	}
11343dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
11353dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
11363dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//===========================================================================================================================
11373dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//	mDNSPlatformTCPCloseConnection
11383dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//===========================================================================================================================
11393dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
11403dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinmDNSexport void	mDNSPlatformTCPCloseConnection( TCPSocket *sock )
11413dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin{
11423dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	check( sock );
11433dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
11443dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	if ( sock->connectEvent && sock->m->p->unregisterWaitableEventFunc )
11453dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	{
11463dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		sock->m->p->unregisterWaitableEventFunc( sock->m, sock->connectEvent );
11473dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	}
11483dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
11493dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	if ( sock->fd != INVALID_SOCKET )
11503dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	{
11513dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		TCPCloseSocket( sock );
11523dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
11533dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		QueueUserAPC( ( PAPCFUNC ) TCPFreeSocket, sock->m->p->mainThread, ( ULONG_PTR ) sock );
11543dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	}
11553dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin}
11563dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
11573dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
11583dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//===========================================================================================================================
11593dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//	mDNSPlatformReadTCP
11603dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//===========================================================================================================================
11613dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
11623dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinmDNSexport long	mDNSPlatformReadTCP( TCPSocket *sock, void *inBuffer, unsigned long inBufferSize, mDNSBool * closed )
11633dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin{
11643dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	unsigned long	bytesLeft;
11653dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	int				wsaError;
11663dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	long			ret;
11673dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
11683dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	*closed = sock->closed;
11693dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	wsaError = sock->lastError;
11703dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	ret = -1;
11713dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
11723dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	if ( *closed )
11733dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	{
11743dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		ret = 0;
11753dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	}
11763dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	else if ( sock->lastError == 0 )
11773dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	{
11783dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		// First check to see if we have any data left in our buffer
11793dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
11803dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		bytesLeft = ( DWORD ) ( sock->eptr - sock->bptr );
11813dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
11823dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		if ( bytesLeft )
11833dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		{
11843dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			unsigned long bytesToCopy = ( bytesLeft < inBufferSize ) ? bytesLeft : inBufferSize;
11853dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
11863dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			memcpy( inBuffer, sock->bptr, bytesToCopy );
11873dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			sock->bptr += bytesToCopy;
11883dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
11893dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			if ( !sock->overlapped.pending && ( sock->bptr == sock->eptr ) )
11903dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			{
11913dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin				sock->bptr = sock->bbuf;
11923dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin				sock->eptr = sock->bbuf;
11933dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			}
11943dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
11953dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			ret = bytesToCopy;
11963dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		}
11973dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		else
11983dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		{
11993dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			wsaError = WSAEWOULDBLOCK;
12003dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		}
12013dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	}
12023dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
12033dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	// Always set the last winsock error, so that we don't inadvertently use a previous one
12043dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
12053dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	WSASetLastError( wsaError );
12063dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
12073dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	return ret;
12083dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin}
12093dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
12103dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
12113dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//===========================================================================================================================
12123dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//	mDNSPlatformWriteTCP
12133dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//===========================================================================================================================
12143dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
12153dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinmDNSexport long	mDNSPlatformWriteTCP( TCPSocket *sock, const char *inMsg, unsigned long inMsgSize )
12163dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin{
12173dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	int			nsent;
12183dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	OSStatus	err;
12193dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
12203dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	nsent = send( sock->fd, inMsg, inMsgSize, 0 );
12213dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
12223dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	err = translate_errno( ( nsent >= 0 ) || ( WSAGetLastError() == WSAEWOULDBLOCK ), WSAGetLastError(), mStatus_UnknownErr );
12233dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	require_noerr( err, exit );
12243dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
12253dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	if ( nsent < 0)
12263dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	{
12273dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		nsent = 0;
12283dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	}
12293dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
12303dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlinexit:
12313dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
12323dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	return nsent;
12333dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin}
12343dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
12353dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//===========================================================================================================================
12363dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//	mDNSPlatformTCPGetFD
12373dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//===========================================================================================================================
12383dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
12393dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinmDNSexport int mDNSPlatformTCPGetFD(TCPSocket *sock )
12403dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin{
12413dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	return ( int ) sock->fd;
12423dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin}
12433dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
12443dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
12453dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//===========================================================================================================================
12463dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//	TCPAddConnection
12473dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//===========================================================================================================================
12483dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
12493dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinmStatus TCPAddSocket( mDNS * const inMDNS, TCPSocket *sock )
12503dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin{
12513dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	mStatus err;
12523dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
12533dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	( void ) inMDNS;
12543dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
12553dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	sock->bptr	= sock->bbuf;
12563dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	sock->eptr	= sock->bbuf;
12573dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	sock->ebuf	= sock->bbuf + sizeof( sock->bbuf );
12583dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
12593dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	dlog( kDebugLevelChatty, DEBUG_NAME "adding TCPSocket 0x%x:%d\n", sock, sock->fd );
12603dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	err = TCPBeginRecv( sock );
12613dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	require_noerr( err, exit );
12623dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
12633dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlinexit:
12643dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
12653dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	return err;
12663dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin}
12673dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
12683dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
12693dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//===========================================================================================================================
12703dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//	TCPDidConnect
12713dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//===========================================================================================================================
12723dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
12733dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinmDNSlocal void TCPDidConnect( mDNS * const inMDNS, HANDLE event, void * context )
12743dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin{
12753dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	TCPSocket * sock = ( TCPSocket* ) context;
12763dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	TCPConnectionCallback callback = NULL;
12773dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	WSANETWORKEVENTS sockEvent;
12783dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	int err = kNoErr;
12793dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
12803dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	if ( inMDNS->p->unregisterWaitableEventFunc )
12813dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	{
12823dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		inMDNS->p->unregisterWaitableEventFunc( inMDNS, event );
12833dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	}
12843dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
12853dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	if ( sock )
12863dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	{
12873dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		callback = ( TCPConnectionCallback ) sock->userCallback;
12883dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		err = WSAEnumNetworkEvents( sock->fd, sock->connectEvent, &sockEvent );
12893dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		require_noerr( err, exit );
12903dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		require_action( sockEvent.lNetworkEvents & FD_CONNECT, exit, err = mStatus_UnknownErr );
12913dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		require_action( sockEvent.iErrorCode[ FD_CONNECT_BIT ] == 0, exit, err = sockEvent.iErrorCode[ FD_CONNECT_BIT ] );
12923dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
12933dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		sock->connected	= mDNStrue;
12943dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
12953dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		if ( sock->fd != INVALID_SOCKET )
12963dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		{
12973dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			err = TCPAddSocket( sock->m, sock );
12983dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			require_noerr( err, exit );
12993dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		}
13003dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
13013dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		if ( callback )
13023dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		{
13033dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			callback( sock, sock->userContext, TRUE, 0 );
13043dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		}
13053dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	}
13063dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
13073dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlinexit:
13083dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
13093dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	if ( err && callback )
13103dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	{
13113dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		callback( sock, sock->userContext, TRUE, err );
13123dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	}
13133dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin}
13143dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
13153dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
13163dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
13173dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//===========================================================================================================================
13183dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//	TCPCanRead
13193dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//===========================================================================================================================
13203dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
13213dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinmDNSlocal void TCPCanRead( TCPSocket * sock )
13223dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin{
13233dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	TCPConnectionCallback callback = ( TCPConnectionCallback ) sock->userCallback;
13243dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
13253dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	if ( callback )
13263dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	{
13273dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		callback( sock, sock->userContext, mDNSfalse, sock->lastError );
13283dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	}
13293dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin}
13303dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
13313dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
13323dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//===========================================================================================================================
13333dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//	TCPBeginRecv
13343dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//===========================================================================================================================
13353dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
13363dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinmDNSlocal mStatus TCPBeginRecv( TCPSocket * sock )
13373dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin{
13383dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	DWORD	bytesReceived	= 0;
13393dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	DWORD	flags			= 0;
13403dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	mStatus err;
13413dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
13423dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	dlog( kDebugLevelChatty, DEBUG_NAME "%s: sock = %d\n", __ROUTINE__, sock->fd );
13433dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
13443dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	check( !sock->overlapped.pending );
13453dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
13463dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	ZeroMemory( &sock->overlapped.data, sizeof( sock->overlapped.data ) );
13473dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	sock->overlapped.data.hEvent = sock;
13483dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
13493dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	sock->overlapped.wbuf.buf = ( char* ) sock->eptr;
13503dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	sock->overlapped.wbuf.len = ( ULONG) ( sock->ebuf - sock->eptr );
13513dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
13523dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	err = WSARecv( sock->fd, &sock->overlapped.wbuf, 1, &bytesReceived, &flags, &sock->overlapped.data, ( LPWSAOVERLAPPED_COMPLETION_ROUTINE ) TCPEndRecv );
13533dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	err = translate_errno( ( err == 0 ) || ( WSAGetLastError() == WSA_IO_PENDING ), WSAGetLastError(), kUnknownErr );
13543dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	require_noerr( err, exit );
13553dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
13563dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	sock->overlapped.pending = TRUE;
13573dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
13583dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlinexit:
13593dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
13603dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	return err;
13613dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin}
13623dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
13633dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
13643dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//===========================================================================================================================
13653dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//	TCPEndRecv
13663dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//===========================================================================================================================
13673dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
13683dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinmDNSlocal void CALLBACK TCPEndRecv( DWORD error, DWORD bytesTransferred, LPWSAOVERLAPPED overlapped, DWORD flags )
13693dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin{
13703dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	TCPSocket * sock;
13713dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
13723dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	( void ) flags;
13733dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
13743dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	dlog( kDebugLevelChatty, DEBUG_NAME "%s: error = %d, bytesTransferred = %d\n", __ROUTINE__, error, bytesTransferred );
13753dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	sock = ( overlapped != NULL ) ? overlapped->hEvent : NULL;
13763dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	require_action( sock, exit, error = ( DWORD ) mStatus_BadStateErr );
13773dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	dlog( kDebugLevelChatty, DEBUG_NAME "%s: sock = %d\n", __ROUTINE__, sock->fd );
13783dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	sock->overlapped.error				= error;
13793dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	sock->overlapped.bytesTransferred	= bytesTransferred;
13803dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	check( sock->overlapped.pending );
13813dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	sock->overlapped.pending			= FALSE;
13823dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
13833dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	// Queue this socket
13843dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
13853dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	AddToTail( &gTCPDispatchableSockets, sock );
13863dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
13873dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlinexit:
13883dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
13893dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	return;
13903dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin}
13913dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
13923dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
13933dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
13943dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//===========================================================================================================================
13953dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//	mDNSPlatformUDPSocket
13963dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//===========================================================================================================================
13973dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
13983dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinmDNSexport UDPSocket* mDNSPlatformUDPSocket(mDNS *const m, const mDNSIPPort requestedport)
13993dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin{
14003dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	UDPSocket*	sock	= NULL;
14013dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	mDNSIPPort	port	= requestedport;
14023dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	mStatus		err		= mStatus_NoError;
14033dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	unsigned	i;
14043dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
14053dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	// Setup connection data object
14063dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
14073dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	sock = ( UDPSocket* ) malloc(sizeof( UDPSocket ) );
14083dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	require_action( sock, exit, err = mStatus_NoMemoryErr );
14093dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	memset( sock, 0, sizeof( UDPSocket ) );
14103dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
14113dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	// Create the socket
14123dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
14133dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	sock->fd					= INVALID_SOCKET;
14143dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	sock->recvMsgPtr			= m->p->unicastSock4.recvMsgPtr;
14153dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	sock->addr					= m->p->unicastSock4.addr;
14163dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	sock->ifd					= NULL;
14173dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	sock->overlapped.pending	= FALSE;
14183dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	sock->m						= m;
14193dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
14203dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	// Try at most 10000 times to get a unique random port
14213dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
14223dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	for (i=0; i<10000; i++)
14233dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	{
14243dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		struct sockaddr_in saddr;
14253dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
14263dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		saddr.sin_family		= AF_INET;
14273dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		saddr.sin_addr.s_addr	= 0;
14283dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
14293dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		// The kernel doesn't do cryptographically strong random port
14303dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		// allocation, so we do it ourselves here
14313dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
14323dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin        if (mDNSIPPortIsZero(requestedport))
14333dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		{
14343dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			port = mDNSOpaque16fromIntVal( ( mDNSu16 ) ( 0xC000 + mDNSRandom(0x3FFF) ) );
14353dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		}
14363dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
14373dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		saddr.sin_port = port.NotAnInteger;
14383dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
14393dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin        err = SetupSocket(m, ( struct sockaddr* ) &saddr, port, &sock->fd );
14403dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin        if (!err) break;
14413dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	}
14423dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
14433dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	require_noerr( err, exit );
14443dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
14453dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	// Set the port
14463dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
14473dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	sock->port = port;
14483dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
14493dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	// Arm the completion routine
14503dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
14513dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	err = UDPBeginRecv( sock );
14523dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	require_noerr( err, exit );
14533dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
14543dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	// Bookkeeping
14553dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
14563dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	sock->next		= gUDPSockets;
14573dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	gUDPSockets		= sock;
14583dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	gUDPNumSockets++;
14593dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
14603dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlinexit:
14613dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
14623dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	if ( err && sock )
14633dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	{
14643dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		UDPFreeSocket( sock );
14653dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		sock = NULL;
14663dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	}
14673dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
14683dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	return sock;
14693dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin}
14703dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
14713dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//===========================================================================================================================
14723dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//	mDNSPlatformUDPClose
14733dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//===========================================================================================================================
14743dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
14753dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinmDNSexport void mDNSPlatformUDPClose( UDPSocket *sock )
14763dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin{
14773dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	UDPSocket	*	current  = gUDPSockets;
14783dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	UDPSocket	*	last = NULL;
14793dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
14803dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	while ( current )
14813dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	{
14823dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		if ( current == sock )
14833dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		{
14843dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			if ( last == NULL )
14853dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			{
14863dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin				gUDPSockets = sock->next;
14873dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			}
14883dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			else
14893dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			{
14903dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin				last->next = sock->next;
14913dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			}
14923dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
14933dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			// Alertable I/O is great, except not so much when it comes to closing
14943dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			// the socket.  Anything that has been previously queued for this socket
14953dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			// will stay in the queue after you close the socket.  This is problematic
14963dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			// for obvious reasons. So we'll attempt to workaround this by closing
14973dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			// the socket which will prevent any further queued packets and then not calling
14983dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			// UDPFreeSocket directly, but by queueing it using QueueUserAPC.  The queues
14993dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			// are FIFO, so that will execute *after* any other previous items in the queue
15003dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			//
15013dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			// UDPEndRecv will check if the socket is valid, and if not, it will ignore
15023dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			// the packet
15033dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
15043dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			UDPCloseSocket( sock );
15053dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
15063dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			QueueUserAPC( ( PAPCFUNC ) UDPFreeSocket, sock->m->p->mainThread, ( ULONG_PTR ) sock );
15073dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
15083dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			gUDPNumSockets--;
15093dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
15103dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			break;
15113dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		}
15123dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
15133dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		last	= current;
15143dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		current	= current->next;
15153dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	}
15163dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin}
15173dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
15183dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
15193dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//===========================================================================================================================
15203dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//	mDNSPlatformSendUDP
15213dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//===========================================================================================================================
15223dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
15233dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinmDNSexport mStatus
15243dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	mDNSPlatformSendUDP(
15253dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		const mDNS * const			inMDNS,
15263dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		const void * const	        inMsg,
15273dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		const mDNSu8 * const		inMsgEnd,
15283dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		mDNSInterfaceID 			inInterfaceID,
15293dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		UDPSocket *					inSrcSocket,
15303dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		const mDNSAddr *			inDstIP,
15313dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		mDNSIPPort 					inDstPort )
15323dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin{
15333dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	SOCKET						sendingsocket = INVALID_SOCKET;
15343dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	mStatus						err = mStatus_NoError;
15353dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	mDNSInterfaceData *			ifd = (mDNSInterfaceData*) inInterfaceID;
15363dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	struct sockaddr_storage		addr;
15373dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	int							n;
15383dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
15393dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	DEBUG_USE_ONLY( inMDNS );
15403dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
15413dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	n = (int)( inMsgEnd - ( (const mDNSu8 * const) inMsg ) );
15423dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	check( inMDNS );
15433dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	check( inMsg );
15443dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	check( inMsgEnd );
15453dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	check( inDstIP );
15463dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
15473dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	dlog( kDebugLevelChatty, DEBUG_NAME "platform send %d bytes to %#a:%u\n", n, inDstIP, ntohs( inDstPort.NotAnInteger ) );
15483dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
15493dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	if( inDstIP->type == mDNSAddrType_IPv4 )
15503dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	{
15513dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		struct sockaddr_in *		sa4;
15523dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
15533dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		sa4						= (struct sockaddr_in *) &addr;
15543dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		sa4->sin_family			= AF_INET;
15553dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		sa4->sin_port			= inDstPort.NotAnInteger;
15563dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		sa4->sin_addr.s_addr	= inDstIP->ip.v4.NotAnInteger;
15573dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		sendingsocket           = ifd ? ifd->sock.fd : inMDNS->p->unicastSock4.fd;
15583dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
15593dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		if (inSrcSocket) { sendingsocket = inSrcSocket->fd; debugf("mDNSPlatformSendUDP using port %d, static port %d, sock %d", mDNSVal16(inSrcSocket->port), inMDNS->p->unicastSock4.fd, sendingsocket); }
15603dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	}
15613dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	else if( inDstIP->type == mDNSAddrType_IPv6 )
15623dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	{
15633dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		struct sockaddr_in6 *		sa6;
15643dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
15653dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		sa6					= (struct sockaddr_in6 *) &addr;
15663dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		sa6->sin6_family	= AF_INET6;
15673dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		sa6->sin6_port		= inDstPort.NotAnInteger;
15683dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		sa6->sin6_flowinfo	= 0;
15693dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		sa6->sin6_addr		= *( (struct in6_addr *) &inDstIP->ip.v6 );
15703dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		sa6->sin6_scope_id	= 0;	// Windows requires the scope ID to be zero. IPV6_MULTICAST_IF specifies interface.
15713dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		sendingsocket		= ifd ? ifd->sock.fd : inMDNS->p->unicastSock6.fd;
15723dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	}
15733dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	else
15743dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	{
15753dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		dlog( kDebugLevelError, DEBUG_NAME "%s: dst is not an IPv4 or IPv6 address (type=%d)\n", __ROUTINE__, inDstIP->type );
15763dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		err = mStatus_BadParamErr;
15773dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		goto exit;
15783dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	}
15793dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
15803dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	if (IsValidSocket(sendingsocket))
15813dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	{
15823dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		n = sendto( sendingsocket, (char *) inMsg, n, 0, (struct sockaddr *) &addr, sizeof( addr ) );
15833dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		err = translate_errno( n > 0, errno_compat(), kWriteErr );
15843dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
15853dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		if ( err )
15863dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		{
15873dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			// Don't report EHOSTDOWN (i.e. ARP failure), ENETDOWN, or no route to host for unicast destinations
15883dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
15893dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			if ( !mDNSAddressIsAllDNSLinkGroup( inDstIP ) && ( WSAGetLastError() == WSAEHOSTDOWN || WSAGetLastError() == WSAENETDOWN || WSAGetLastError() == WSAEHOSTUNREACH || WSAGetLastError() == WSAENETUNREACH ) )
15903dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			{
15913dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin				err = mStatus_TransientErr;
15923dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			}
15933dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			else
15943dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			{
15953dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin				require_noerr( err, exit );
15963dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			}
15973dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		}
15983dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	}
15993dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
16003dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlinexit:
16013dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	return( err );
16023dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin}
16033dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
16043dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
16053dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinmDNSexport void mDNSPlatformUpdateProxyList(mDNS *const m, const mDNSInterfaceID InterfaceID)
16063dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	{
16073dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	DEBUG_UNUSED( m );
16083dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	DEBUG_UNUSED( InterfaceID );
16093dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	}
16103dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
16113dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//===========================================================================================================================
16123dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//	mDNSPlatformSendRawPacket
16133dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//===========================================================================================================================
16143dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
16153dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinmDNSexport void mDNSPlatformSetAllowSleep(mDNS *const m, mDNSBool allowSleep, const char *reason)
16163dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin    {
16173dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin    DEBUG_UNUSED( m );
16183dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	DEBUG_UNUSED( allowSleep );
16193dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	DEBUG_UNUSED( reason );
16203dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin    }
16213dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
16223dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinmDNSexport void mDNSPlatformSendRawPacket(const void *const msg, const mDNSu8 *const end, mDNSInterfaceID InterfaceID)
16233dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	{
16243dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	DEBUG_UNUSED( msg );
16253dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	DEBUG_UNUSED( end );
16263dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	DEBUG_UNUSED( InterfaceID );
16273dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	}
16283dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
16293dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinmDNSexport void mDNSPlatformReceiveRawPacket(const void *const msg, const mDNSu8 *const end, mDNSInterfaceID InterfaceID)
16303dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	{
16313dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	DEBUG_UNUSED( msg );
16323dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	DEBUG_UNUSED( end );
16333dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	DEBUG_UNUSED( InterfaceID );
16343dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	}
16353dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
16363dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinmDNSexport void mDNSPlatformSetLocalAddressCacheEntry(mDNS *const m, const mDNSAddr *const tpa, const mDNSEthAddr *const tha, mDNSInterfaceID InterfaceID)
16373dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	{
16383dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	DEBUG_UNUSED( m );
16393dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	DEBUG_UNUSED( tpa );
16403dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	DEBUG_UNUSED( tha );
16413dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	DEBUG_UNUSED( InterfaceID );
16423dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	}
16433dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
16443dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinmDNSexport void mDNSPlatformWriteDebugMsg(const char *msg)
16453dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	{
16463dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	dlog( kDebugLevelInfo, "%s\n", msg );
16473dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	}
16483dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
16493dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinmDNSexport void mDNSPlatformWriteLogMsg( const char * ident, const char * msg, mDNSLogLevel_t loglevel )
16503dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	{
16513dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	extern mDNS mDNSStorage;
16523dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	int type;
16533dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
16543dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	DEBUG_UNUSED( ident );
16553dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
16563dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	type = EVENTLOG_ERROR_TYPE;
16573dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
16583dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	switch (loglevel)
16593dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	{
16603dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		case MDNS_LOG_MSG:       type = EVENTLOG_ERROR_TYPE;		break;
16613dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		case MDNS_LOG_OPERATION: type = EVENTLOG_WARNING_TYPE;		break;
16623dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		case MDNS_LOG_SPS:       type = EVENTLOG_INFORMATION_TYPE;  break;
16633dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		case MDNS_LOG_INFO:      type = EVENTLOG_INFORMATION_TYPE;	break;
16643dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		case MDNS_LOG_DEBUG:     type = EVENTLOG_INFORMATION_TYPE;	break;
16653dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		default:
16663dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			fprintf(stderr, "Unknown loglevel %d, assuming LOG_ERR\n", loglevel);
16673dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			fflush(stderr);
16683dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			}
16693dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
16703dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	mDNSStorage.p->reportStatusFunc( type, msg );
16713dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	dlog( kDebugLevelInfo, "%s\n", msg );
16723dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	}
16733dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
16743dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinmDNSexport void mDNSPlatformSourceAddrForDest( mDNSAddr * const src, const mDNSAddr * const dst )
16753dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	{
16763dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	DEBUG_UNUSED( src );
16773dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	DEBUG_UNUSED( dst );
16783dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	}
16793dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
16803dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//===========================================================================================================================
16813dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//	mDNSPlatformTLSSetupCerts
16823dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//===========================================================================================================================
16833dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
16843dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinmDNSexport mStatus
16853dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinmDNSPlatformTLSSetupCerts(void)
16863dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin{
16873dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	return mStatus_UnsupportedErr;
16883dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin}
16893dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
16903dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//===========================================================================================================================
16913dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//	mDNSPlatformTLSTearDownCerts
16923dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//===========================================================================================================================
16933dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
16943dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinmDNSexport void
16953dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinmDNSPlatformTLSTearDownCerts(void)
16963dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin{
16973dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin}
16983dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
16993dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//===========================================================================================================================
17003dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//	mDNSPlatformSetDNSConfig
17013dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//===========================================================================================================================
17023dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
17033dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinmDNSlocal void SetDNSServers( mDNS *const m );
17043dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinmDNSlocal void SetSearchDomainList( void );
17053dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
17063dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinmDNSexport void mDNSPlatformSetDNSConfig(mDNS *const m, mDNSBool setservers, mDNSBool setsearch, domainname *const fqdn, DNameListElem **regDomains, DNameListElem **browseDomains)
17073dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin{
17083dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	if (setservers) SetDNSServers(m);
17093dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	if (setsearch) SetSearchDomainList();
17103dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
17113dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	if ( fqdn )
17123dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	{
17133dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		GetDDNSFQDN( fqdn );
17143dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	}
17153dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
17163dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	if ( browseDomains )
17173dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	{
17183dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		GetDDNSDomains( browseDomains, kServiceParametersNode TEXT("\\DynDNS\\Setup\\") kServiceDynDNSBrowseDomains );
17193dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	}
17203dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
17213dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	if ( regDomains )
17223dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	{
17233dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		GetDDNSDomains( regDomains, kServiceParametersNode TEXT("\\DynDNS\\Setup\\") kServiceDynDNSRegistrationDomains );
17243dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	}
17253dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin}
17263dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
17273dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
17283dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//===========================================================================================================================
17293dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//	mDNSPlatformDynDNSHostNameStatusChanged
17303dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//===========================================================================================================================
17313dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
17323dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinmDNSexport void
17333dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinmDNSPlatformDynDNSHostNameStatusChanged(const domainname *const dname, const mStatus status)
17343dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin{
17353dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	char		uname[MAX_ESCAPED_DOMAIN_NAME];
17363dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	BYTE		bStatus;
17373dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	LPCTSTR		name;
17383dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	HKEY		key = NULL;
17393dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	mStatus		err;
17403dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	char	*	p;
17413dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
17423dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	ConvertDomainNameToCString(dname, uname);
17433dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
17443dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	p = uname;
17453dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
17463dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	while (*p)
17473dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	{
17483dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		*p = (char) tolower(*p);
17493dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		if (!(*(p+1)) && *p == '.') *p = 0; // if last character, strip trailing dot
17503dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		p++;
17513dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	}
17523dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
17533dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	check( strlen( p ) <= MAX_ESCAPED_DOMAIN_NAME );
17543dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	name = kServiceParametersNode TEXT("\\DynDNS\\State\\HostNames");
17553dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	err = RegCreateKey( HKEY_LOCAL_MACHINE, name, &key );
17563dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	require_noerr( err, exit );
17573dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
17583dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	bStatus = ( status ) ? 0 : 1;
17593dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	err = RegSetValueEx( key, kServiceDynDNSStatus, 0, REG_DWORD, (const LPBYTE) &bStatus, sizeof(DWORD) );
17603dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	require_noerr( err, exit );
17613dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
17623dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlinexit:
17633dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
17643dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	if ( key )
17653dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	{
17663dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		RegCloseKey( key );
17673dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	}
17683dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
17693dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	return;
17703dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin}
17713dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
17723dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
17733dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinmDNSexport void FreeEtcHosts(mDNS *const m, AuthRecord *const rr, mStatus result)
17743dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin    {
17753dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin    (void)m;  // unused
17763dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin    (void)rr;
17773dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin    (void)result;
17783dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin    }
17793dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
17803dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
17813dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
17823dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//===========================================================================================================================
17833dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//	SetDomainSecrets
17843dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//===========================================================================================================================
17853dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
17863dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin// This routine needs to be called whenever the system secrets database changes.
17873dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin// We call it from DynDNSConfigDidChange and mDNSPlatformInit
17883dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
17893dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlinvoid
17903dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinSetDomainSecrets( mDNS * const m )
17913dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin{
17923dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	DomainAuthInfo *ptr;
17933dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	domainname		fqdn;
17943dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	DNameListElem * regDomains = NULL;
17953dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
17963dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	// Rather than immediately deleting all keys now, we mark them for deletion in ten seconds.
17973dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	// In the case where the user simultaneously removes their DDNS host name and the key
17983dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	// for it, this gives mDNSResponder ten seconds to gracefully delete the name from the
17993dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	// server before it loses access to the necessary key. Otherwise, we'd leave orphaned
18003dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	// address records behind that we no longer have permission to delete.
18013dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
18023dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	for (ptr = m->AuthInfoList; ptr; ptr = ptr->next)
18033dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		ptr->deltime = NonZeroTime(m->timenow + mDNSPlatformOneSecond*10);
18043dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
18053dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	GetDDNSFQDN( &fqdn );
18063dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
18073dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	if ( fqdn.c[ 0 ] )
18083dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	{
18093dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		SetDomainSecret( m, &fqdn );
18103dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	}
18113dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
18123dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	GetDDNSDomains( &regDomains, kServiceParametersNode TEXT("\\DynDNS\\Setup\\") kServiceDynDNSRegistrationDomains );
18133dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
18143dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	while ( regDomains )
18153dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	{
18163dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		DNameListElem * current = regDomains;
18173dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		SetDomainSecret( m, &current->name );
18183dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		regDomains = regDomains->next;
18193dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		free( current );
18203dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	}
18213dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin}
18223dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
18233dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
18243dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//===========================================================================================================================
18253dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//	SetSearchDomainList
18263dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//===========================================================================================================================
18273dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
18283dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinmDNSlocal void SetDomainFromDHCP( void );
18293dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinmDNSlocal void SetReverseMapSearchDomainList( void );
18303dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
18313dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinmDNSlocal void
18323dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinSetSearchDomainList( void )
18333dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin{
18343dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	char			*	searchList	= NULL;
18353dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	DWORD				searchListLen;
18363dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	//DNameListElem	*	head = NULL;
18373dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	//DNameListElem	*	current = NULL;
18383dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	char			*	tok;
18393dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	HKEY				key;
18403dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	mStatus				err;
18413dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
18423dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	err = RegCreateKey( HKEY_LOCAL_MACHINE, TEXT("SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters"), &key );
18433dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	require_noerr( err, exit );
18443dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
18453dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	err = RegQueryString( key, "SearchList", &searchList, &searchListLen, NULL );
18463dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	require_noerr( err, exit );
18473dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
18483dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	// Windows separates the search domains with ','
18493dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
18503dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	tok = strtok( searchList, "," );
18513dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	while ( tok )
18523dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	{
18533dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		if ( ( strcmp( tok, "" ) != 0 ) && ( strcmp( tok, "." ) != 0 ) )
18543dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			mDNS_AddSearchDomain_CString(tok, mDNSNULL);
18553dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		tok = strtok( NULL, "," );
18563dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	}
18573dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
18583dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlinexit:
18593dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
18603dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	if ( searchList )
18613dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	{
18623dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		free( searchList );
18633dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	}
18643dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
18653dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	if ( key )
18663dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	{
18673dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		RegCloseKey( key );
18683dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	}
18693dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
18703dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	SetDomainFromDHCP();
18713dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	SetReverseMapSearchDomainList();
18723dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin}
18733dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
18743dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
18753dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//===========================================================================================================================
18763dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//	SetReverseMapSearchDomainList
18773dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//===========================================================================================================================
18783dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
18793dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinmDNSlocal void
18803dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinSetReverseMapSearchDomainList( void )
18813dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin{
18823dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	struct ifaddrs	*	ifa;
18833dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
18843dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	ifa = myGetIfAddrs( 1 );
18853dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	while (ifa)
18863dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	{
18873dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		mDNSAddr addr;
18883dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
18893dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		if (ifa->ifa_addr->sa_family == AF_INET && !SetupAddr(&addr, ifa->ifa_addr) && !(ifa->ifa_flags & IFF_LOOPBACK) && ifa->ifa_netmask)
18903dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		{
18913dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			mDNSAddr	netmask;
18923dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			char		buffer[256];
18933dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
18943dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			if (!SetupAddr(&netmask, ifa->ifa_netmask))
18953dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			{
18963dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin				sprintf(buffer, "%d.%d.%d.%d.in-addr.arpa.", addr.ip.v4.b[3] & netmask.ip.v4.b[3],
18973dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin                                                             addr.ip.v4.b[2] & netmask.ip.v4.b[2],
18983dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin                                                             addr.ip.v4.b[1] & netmask.ip.v4.b[1],
18993dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin                                                             addr.ip.v4.b[0] & netmask.ip.v4.b[0]);
19003dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin				mDNS_AddSearchDomain_CString(buffer, mDNSNULL);
19013dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			}
19023dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		}
19033dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
19043dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		ifa = ifa->ifa_next;
19053dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	}
19063dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
19073dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	return;
19083dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin}
19093dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
19103dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
19113dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//===========================================================================================================================
19123dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//	SetDNSServers
19133dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//===========================================================================================================================
19143dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
19153dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinmDNSlocal void
19163dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinSetDNSServers( mDNS *const m )
19173dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin{
19183dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	PIP_PER_ADAPTER_INFO	pAdapterInfo	=	NULL;
19193dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	FIXED_INFO			*	fixedInfo	= NULL;
19203dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	ULONG					bufLen		= 0;
19213dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	IP_ADDR_STRING		*	dnsServerList;
19223dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	IP_ADDR_STRING		*	ipAddr;
19233dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	DWORD					index;
19243dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	int						i			= 0;
19253dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	mStatus					err			= kUnknownErr;
19263dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
19273dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	// Get the primary interface.
19283dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
19293dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	index = GetPrimaryInterface();
19303dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
19313dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	// This should have the interface index of the primary index.  Fall back in cases where
19323dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	// it can't be determined.
19333dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
19343dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	if ( index )
19353dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	{
19363dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		bufLen = 0;
19373dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
19383dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		for ( i = 0; i < 100; i++ )
19393dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		{
19403dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			err = GetPerAdapterInfo( index, pAdapterInfo, &bufLen );
19413dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
19423dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			if ( err != ERROR_BUFFER_OVERFLOW )
19433dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			{
19443dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin				break;
19453dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			}
19463dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
19473dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			pAdapterInfo = (PIP_PER_ADAPTER_INFO) realloc( pAdapterInfo, bufLen );
19483dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			require_action( pAdapterInfo, exit, err = mStatus_NoMemoryErr );
19493dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		}
19503dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
19513dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		require_noerr( err, exit );
19523dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
19533dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		dnsServerList = &pAdapterInfo->DnsServerList;
19543dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	}
19553dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	else
19563dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	{
19573dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		bufLen = sizeof( FIXED_INFO );
19583dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
19593dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		for ( i = 0; i < 100; i++ )
19603dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		{
19613dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			if ( fixedInfo )
19623dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			{
19633dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin				GlobalFree( fixedInfo );
19643dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin				fixedInfo = NULL;
19653dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			}
19663dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
19673dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			fixedInfo = (FIXED_INFO*) GlobalAlloc( GPTR, bufLen );
19683dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			require_action( fixedInfo, exit, err = mStatus_NoMemoryErr );
19693dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
19703dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			err = GetNetworkParams( fixedInfo, &bufLen );
19713dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
19723dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			if ( err != ERROR_BUFFER_OVERFLOW )
19733dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			{
19743dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin				break;
19753dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			}
19763dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		}
19773dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
19783dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		require_noerr( err, exit );
19793dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
19803dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		dnsServerList = &fixedInfo->DnsServerList;
19813dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	}
19823dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
19833dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	for ( ipAddr = dnsServerList; ipAddr; ipAddr = ipAddr->Next )
19843dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	{
19853dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		mDNSAddr addr;
19863dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		err = StringToAddress( &addr, ipAddr->IpAddress.String );
19873dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		if ( !err ) mDNS_AddDNSServer(m, mDNSNULL, mDNSInterface_Any, &addr, UnicastDNSPort, mDNSfalse, 0);
19883dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	}
19893dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
19903dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlinexit:
19913dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
19923dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	if ( pAdapterInfo )
19933dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	{
19943dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		free( pAdapterInfo );
19953dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	}
19963dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
19973dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	if ( fixedInfo )
19983dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	{
19993dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		GlobalFree( fixedInfo );
20003dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	}
20013dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin}
20023dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
20033dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
20043dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//===========================================================================================================================
20053dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//	SetDomainFromDHCP
20063dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//===========================================================================================================================
20073dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
20083dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinmDNSlocal void
20093dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinSetDomainFromDHCP( void )
20103dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin{
20113dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	int					i			= 0;
20123dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	IP_ADAPTER_INFO *	pAdapterInfo;
20133dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	IP_ADAPTER_INFO *	pAdapter;
20143dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	DWORD				bufLen;
20153dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	DWORD				index;
20163dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	HKEY				key = NULL;
20173dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	LPSTR				domain = NULL;
20183dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	DWORD				dwSize;
20193dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	mStatus				err = mStatus_NoError;
20203dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
20213dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	pAdapterInfo	= NULL;
20223dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
20233dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	for ( i = 0; i < 100; i++ )
20243dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	{
20253dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		err = GetAdaptersInfo( pAdapterInfo, &bufLen);
20263dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
20273dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		if ( err != ERROR_BUFFER_OVERFLOW )
20283dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		{
20293dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			break;
20303dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		}
20313dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
20323dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		pAdapterInfo = (IP_ADAPTER_INFO*) realloc( pAdapterInfo, bufLen );
20333dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		require_action( pAdapterInfo, exit, err = kNoMemoryErr );
20343dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	}
20353dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
20363dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	require_noerr( err, exit );
20373dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
20383dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	index = GetPrimaryInterface();
20393dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
20403dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	for ( pAdapter = pAdapterInfo; pAdapter; pAdapter = pAdapter->Next )
20413dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	{
20423dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		if ( pAdapter->IpAddressList.IpAddress.String &&
20433dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		     pAdapter->IpAddressList.IpAddress.String[0] &&
20443dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		     pAdapter->GatewayList.IpAddress.String &&
20453dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		     pAdapter->GatewayList.IpAddress.String[0] &&
20463dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		     ( !index || ( pAdapter->Index == index ) ) )
20473dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		{
20483dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			// Found one that will work
20493dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
20503dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			char keyName[1024];
20513dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
20523dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			_snprintf( keyName, 1024, "%s%s", "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Interfaces\\", pAdapter->AdapterName );
20533dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
20543dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			err = RegCreateKeyA( HKEY_LOCAL_MACHINE, keyName, &key );
20553dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			require_noerr( err, exit );
20563dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
20573dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			err = RegQueryString( key, "Domain", &domain, &dwSize, NULL );
20583dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			check_noerr( err );
20593dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
20603dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			if ( !domain || !domain[0] )
20613dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			{
20623dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin				if ( domain )
20633dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin				{
20643dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin					free( domain );
20653dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin					domain = NULL;
20663dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin				}
20673dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
20683dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin				err = RegQueryString( key, "DhcpDomain", &domain, &dwSize, NULL );
20693dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin				check_noerr( err );
20703dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			}
20713dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
20723dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			if ( domain && domain[0] ) mDNS_AddSearchDomain_CString(domain, mDNSNULL);
20733dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
20743dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			break;
20753dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		}
20763dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	}
20773dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
20783dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlinexit:
20793dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
20803dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	if ( pAdapterInfo )
20813dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	{
20823dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		free( pAdapterInfo );
20833dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	}
20843dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
20853dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	if ( domain )
20863dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	{
20873dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		free( domain );
20883dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	}
20893dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
20903dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	if ( key )
20913dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	{
20923dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		RegCloseKey( key );
20933dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	}
20943dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin}
20953dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
20963dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
20973dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//===========================================================================================================================
20983dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//	mDNSPlatformGetPrimaryInterface
20993dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//===========================================================================================================================
21003dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
21013dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinmDNSexport mStatus
21023dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinmDNSPlatformGetPrimaryInterface( mDNS * const m, mDNSAddr * v4, mDNSAddr * v6, mDNSAddr * router )
21033dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin{
21043dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	IP_ADAPTER_INFO *	pAdapterInfo;
21053dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	IP_ADAPTER_INFO *	pAdapter;
21063dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	DWORD				bufLen;
21073dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	int					i;
21083dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	BOOL				found;
21093dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	DWORD				index;
21103dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	mStatus				err = mStatus_NoError;
21113dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
21123dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	DEBUG_UNUSED( m );
21133dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
21143dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	*v6 = zeroAddr;
21153dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
21163dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	pAdapterInfo	= NULL;
21173dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	bufLen			= 0;
21183dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	found			= FALSE;
21193dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
21203dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	for ( i = 0; i < 100; i++ )
21213dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	{
21223dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		err = GetAdaptersInfo( pAdapterInfo, &bufLen);
21233dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
21243dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		if ( err != ERROR_BUFFER_OVERFLOW )
21253dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		{
21263dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			break;
21273dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		}
21283dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
21293dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		pAdapterInfo = (IP_ADAPTER_INFO*) realloc( pAdapterInfo, bufLen );
21303dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		require_action( pAdapterInfo, exit, err = kNoMemoryErr );
21313dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	}
21323dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
21333dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	require_noerr( err, exit );
21343dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
21353dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	index = GetPrimaryInterface();
21363dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
21373dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	for ( pAdapter = pAdapterInfo; pAdapter; pAdapter = pAdapter->Next )
21383dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	{
21393dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		if ( pAdapter->IpAddressList.IpAddress.String &&
21403dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		     pAdapter->IpAddressList.IpAddress.String[0] &&
21413dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		     pAdapter->GatewayList.IpAddress.String &&
21423dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		     pAdapter->GatewayList.IpAddress.String[0] &&
21433dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		     ( StringToAddress( v4, pAdapter->IpAddressList.IpAddress.String ) == mStatus_NoError ) &&
21443dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		     ( StringToAddress( router, pAdapter->GatewayList.IpAddress.String ) == mStatus_NoError ) &&
21453dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		     ( !index || ( pAdapter->Index == index ) ) )
21463dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		{
21473dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			// Found one that will work
21483dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
21493dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			if ( pAdapter->AddressLength == sizeof( m->PrimaryMAC ) )
21503dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			{
21513dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin				memcpy( &m->PrimaryMAC, pAdapter->Address, pAdapter->AddressLength );
21523dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			}
21533dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
21543dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			found = TRUE;
21553dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			break;
21563dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		}
21573dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	}
21583dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
21593dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlinexit:
21603dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
21613dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	if ( pAdapterInfo )
21623dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	{
21633dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		free( pAdapterInfo );
21643dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	}
21653dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
21663dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	return err;
21673dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin}
21683dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
21693dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinmDNSexport void mDNSPlatformSendWakeupPacket(mDNS *const m, mDNSInterfaceID InterfaceID, char *EthAddr, char *IPAddr, int iteration)
21703dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	{
21713dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	(void) m;
21723dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	(void) InterfaceID;
21733dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	(void) EthAddr;
21743dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	(void) IPAddr;
21753dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	(void) iteration;
21763dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	}
21773dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
21783dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinmDNSexport mDNSBool mDNSPlatformValidRecordForInterface(AuthRecord *rr, const NetworkInterfaceInfo *intf)
21793dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	{
21803dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	(void) rr;
21813dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	(void) intf;
21823dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
21833dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	return 1;
21843dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	}
21853dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
21863dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
21873dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin#if 0
21883dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin#pragma mark -
21893dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin#endif
21903dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
21913dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//===========================================================================================================================
21923dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//	debugf_
21933dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//===========================================================================================================================
21943dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin#if( MDNS_DEBUGMSGS )
21953dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinmDNSexport void	debugf_( const char *inFormat, ... )
21963dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin{
21973dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	char		buffer[ 512 ];
21983dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin    va_list		args;
21993dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin    mDNSu32		length;
22003dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
22013dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	va_start( args, inFormat );
22023dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	length = mDNS_vsnprintf( buffer, sizeof( buffer ), inFormat, args );
22033dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	va_end( args );
22043dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
22053dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	dlog( kDebugLevelInfo, "%s\n", buffer );
22063dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin}
22073dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin#endif
22083dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
22093dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//===========================================================================================================================
22103dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//	verbosedebugf_
22113dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//===========================================================================================================================
22123dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
22133dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin#if( MDNS_DEBUGMSGS > 1 )
22143dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinmDNSexport void	verbosedebugf_( const char *inFormat, ... )
22153dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin{
22163dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	char		buffer[ 512 ];
22173dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin    va_list		args;
22183dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin    mDNSu32		length;
22193dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
22203dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	va_start( args, inFormat );
22213dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	length = mDNS_vsnprintf( buffer, sizeof( buffer ), inFormat, args );
22223dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	va_end( args );
22233dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
22243dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	dlog( kDebugLevelVerbose, "%s\n", buffer );
22253dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin}
22263dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin#endif
22273dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
22283dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
22293dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin#if 0
22303dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin#pragma mark -
22313dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin#pragma mark == Platform Internals  ==
22323dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin#endif
22333dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
22343dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
22353dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//===========================================================================================================================
22363dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//	SetupNiceName
22373dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//===========================================================================================================================
22383dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
22393dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinmStatus	SetupNiceName( mDNS * const inMDNS )
22403dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin{
22413dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	HKEY		descKey = NULL;
22423dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	char		utf8[ 256 ];
22433dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	LPCTSTR		s;
22443dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	LPWSTR		joinName;
22453dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	NETSETUP_JOIN_STATUS joinStatus;
22463dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	mStatus		err = 0;
22473dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	DWORD		namelen;
22483dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	BOOL		ok;
22493dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
22503dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	check( inMDNS );
22513dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
22523dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	// Set up the nice name.
22533dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	utf8[0] = '\0';
22543dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
22553dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	// First try and open the registry key that contains the computer description value
22563dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	s = TEXT("SYSTEM\\CurrentControlSet\\Services\\lanmanserver\\parameters");
22573dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	err = RegOpenKeyEx( HKEY_LOCAL_MACHINE, s, 0, KEY_READ, &descKey);
22583dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	check_translated_errno( err == 0, errno_compat(), kNameErr );
22593dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
22603dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	if ( !err )
22613dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	{
22623dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		TCHAR	desc[256];
22633dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		DWORD	descSize = sizeof( desc );
22643dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
22653dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		// look for the computer description
22663dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		err = RegQueryValueEx( descKey, TEXT("srvcomment"), 0, NULL, (LPBYTE) &desc, &descSize);
22673dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
22683dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		if ( !err )
22693dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		{
22703dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			err = TCHARtoUTF8( desc, utf8, sizeof( utf8 ) );
22713dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		}
22723dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
22733dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		if ( err )
22743dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		{
22753dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			utf8[ 0 ] = '\0';
22763dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		}
22773dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	}
22783dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
22793dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	// if we can't find it in the registry, then use the hostname of the machine
22803dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	if ( err || ( utf8[ 0 ] == '\0' ) )
22813dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	{
22823dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		TCHAR hostname[256];
22833dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
22843dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		namelen = sizeof( hostname ) / sizeof( TCHAR );
22853dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
22863dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		ok = GetComputerNameExW( ComputerNamePhysicalDnsHostname, hostname, &namelen );
22873dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		err = translate_errno( ok, (mStatus) GetLastError(), kNameErr );
22883dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		check_noerr( err );
22893dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
22903dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		if( !err )
22913dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		{
22923dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			err = TCHARtoUTF8( hostname, utf8, sizeof( utf8 ) );
22933dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		}
22943dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
22953dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		if ( err )
22963dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		{
22973dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			utf8[ 0 ] = '\0';
22983dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		}
22993dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	}
23003dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
23013dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	// if we can't get the hostname
23023dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	if ( err || ( utf8[ 0 ] == '\0' ) )
23033dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	{
23043dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		// Invalidate name so fall back to a default name.
23053dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
23063dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		strcpy( utf8, kMDNSDefaultName );
23073dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	}
23083dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
23093dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	utf8[ sizeof( utf8 ) - 1 ]	= '\0';
23103dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	inMDNS->nicelabel.c[ 0 ]	= (mDNSu8) (strlen( utf8 ) < MAX_DOMAIN_LABEL ? strlen( utf8 ) : MAX_DOMAIN_LABEL);
23113dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	memcpy( &inMDNS->nicelabel.c[ 1 ], utf8, inMDNS->nicelabel.c[ 0 ] );
23123dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
23133dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	dlog( kDebugLevelInfo, DEBUG_NAME "nice name \"%.*s\"\n", inMDNS->nicelabel.c[ 0 ], &inMDNS->nicelabel.c[ 1 ] );
23143dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
23153dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	if ( descKey )
23163dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	{
23173dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		RegCloseKey( descKey );
23183dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	}
23193dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
23203dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	ZeroMemory( inMDNS->p->nbname, sizeof( inMDNS->p->nbname ) );
23213dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	ZeroMemory( inMDNS->p->nbdomain, sizeof( inMDNS->p->nbdomain ) );
23223dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
23233dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	namelen = sizeof( inMDNS->p->nbname );
23243dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	ok = GetComputerNameExA( ComputerNamePhysicalNetBIOS, inMDNS->p->nbname, &namelen );
23253dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	check( ok );
23263dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	if ( ok ) dlog( kDebugLevelInfo, DEBUG_NAME "netbios name \"%s\"\n", inMDNS->p->nbname );
23273dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
23283dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	err = NetGetJoinInformation( NULL, &joinName, &joinStatus );
23293dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	check ( err == NERR_Success );
23303dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	if ( err == NERR_Success )
23313dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	{
23323dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		if ( ( joinStatus == NetSetupWorkgroupName ) || ( joinStatus == NetSetupDomainName ) )
23333dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		{
23343dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			err = TCHARtoUTF8( joinName, inMDNS->p->nbdomain, sizeof( inMDNS->p->nbdomain ) );
23353dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			check( !err );
23363dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			if ( !err ) dlog( kDebugLevelInfo, DEBUG_NAME "netbios domain/workgroup \"%s\"\n", inMDNS->p->nbdomain );
23373dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		}
23383dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
23393dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		NetApiBufferFree( joinName );
23403dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		joinName = NULL;
23413dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	}
23423dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
23433dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	err = 0;
23443dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
23453dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	return( err );
23463dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin}
23473dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
23483dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//===========================================================================================================================
23493dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//	SetupHostName
23503dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//===========================================================================================================================
23513dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
23523dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinmDNSlocal mStatus	SetupHostName( mDNS * const inMDNS )
23533dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin{
23543dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	mStatus		err = 0;
23553dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	char		tempString[ 256 ];
23563dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	DWORD		tempStringLen;
23573dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	domainlabel tempLabel;
23583dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	BOOL		ok;
23593dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
23603dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	check( inMDNS );
23613dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
23623dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	// Set up the nice name.
23633dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	tempString[ 0 ] = '\0';
23643dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
23653dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	// use the hostname of the machine
23663dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	tempStringLen = sizeof( tempString );
23673dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	ok = GetComputerNameExA( ComputerNamePhysicalDnsHostname, tempString, &tempStringLen );
23683dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	err = translate_errno( ok, (mStatus) GetLastError(), kNameErr );
23693dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	check_noerr( err );
23703dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
23713dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	// if we can't get the hostname
23723dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	if( err || ( tempString[ 0 ] == '\0' ) )
23733dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	{
23743dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		// Invalidate name so fall back to a default name.
23753dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
23763dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		strcpy( tempString, kMDNSDefaultName );
23773dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	}
23783dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
23793dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	tempString[ sizeof( tempString ) - 1 ] = '\0';
23803dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	tempLabel.c[ 0 ] = (mDNSu8) (strlen( tempString ) < MAX_DOMAIN_LABEL ? strlen( tempString ) : MAX_DOMAIN_LABEL );
23813dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	memcpy( &tempLabel.c[ 1 ], tempString, tempLabel.c[ 0 ] );
23823dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
23833dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	// Set up the host name.
23843dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
23853dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	ConvertUTF8PstringToRFC1034HostLabel( tempLabel.c, &inMDNS->hostlabel );
23863dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	if( inMDNS->hostlabel.c[ 0 ] == 0 )
23873dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	{
23883dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		// Nice name has no characters that are representable as an RFC1034 name (e.g. Japanese) so use the default.
23893dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
23903dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		MakeDomainLabelFromLiteralString( &inMDNS->hostlabel, kMDNSDefaultName );
23913dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	}
23923dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
23933dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	check( inMDNS->hostlabel.c[ 0 ] != 0 );
23943dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
23953dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	mDNS_SetFQDN( inMDNS );
23963dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
23973dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	dlog( kDebugLevelInfo, DEBUG_NAME "host name \"%.*s\"\n", inMDNS->hostlabel.c[ 0 ], &inMDNS->hostlabel.c[ 1 ] );
23983dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
23993dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	return( err );
24003dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin}
24013dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
24023dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//===========================================================================================================================
24033dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//	SetupName
24043dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//===========================================================================================================================
24053dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
24063dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinmDNSlocal mStatus	SetupName( mDNS * const inMDNS )
24073dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin{
24083dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	mStatus		err = 0;
24093dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
24103dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	check( inMDNS );
24113dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
24123dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	err = SetupNiceName( inMDNS );
24133dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	check_noerr( err );
24143dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
24153dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	err = SetupHostName( inMDNS );
24163dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	check_noerr( err );
24173dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
24183dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	return err;
24193dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin}
24203dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
24213dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
24223dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//===========================================================================================================================
24233dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//	SetupInterfaceList
24243dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//===========================================================================================================================
24253dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
24263dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinmStatus	SetupInterfaceList( mDNS * const inMDNS )
24273dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin{
24283dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	mStatus						err;
24293dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	mDNSInterfaceData **		next;
24303dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	mDNSInterfaceData *			ifd;
24313dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	struct ifaddrs *			addrs;
24323dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	struct ifaddrs *			p;
24333dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	struct ifaddrs *			loopbackv4;
24343dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	struct ifaddrs *			loopbackv6;
24353dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	u_int						flagMask;
24363dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	u_int						flagTest;
24373dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	mDNSBool					foundv4;
24383dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	mDNSBool					foundv6;
24393dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	mDNSBool					foundUnicastSock4DestAddr;
24403dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	mDNSBool					foundUnicastSock6DestAddr;
24413dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
24423dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	dlog( kDebugLevelTrace, DEBUG_NAME "setting up interface list\n" );
24433dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	check( inMDNS );
24443dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	check( inMDNS->p );
24453dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
24463dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	inMDNS->p->registeredLoopback4	= mDNSfalse;
24473dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	inMDNS->p->nextDHCPLeaseExpires = 0x7FFFFFFF;
24483dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	addrs							= NULL;
24493dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	foundv4							= mDNSfalse;
24503dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	foundv6							= mDNSfalse;
24513dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	foundUnicastSock4DestAddr		= mDNSfalse;
24523dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	foundUnicastSock6DestAddr		= mDNSfalse;
24533dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
24543dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	// Tear down any existing interfaces that may be set up.
24553dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
24563dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	TearDownInterfaceList( inMDNS );
24573dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
24583dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	// Set up the name of this machine.
24593dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
24603dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	err = SetupName( inMDNS );
24613dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	check_noerr( err );
24623dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
24633dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	// Set up IPv4 interface(s). We have to set up IPv4 first so any IPv6 interface with an IPv4-routable address
24643dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	// can refer to the IPv4 interface when it registers to allow DNS AAAA records over the IPv4 interface.
24653dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
24663dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	err = getifaddrs( &addrs );
24673dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	require_noerr( err, exit );
24683dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
24693dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	loopbackv4	= NULL;
24703dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	loopbackv6	= NULL;
24713dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	next		= &inMDNS->p->interfaceList;
24723dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
24733dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	flagMask = IFF_UP | IFF_MULTICAST;
24743dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	flagTest = IFF_UP | IFF_MULTICAST;
24753dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
24763dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin#if( MDNS_WINDOWS_ENABLE_IPV4 )
24773dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	for( p = addrs; p; p = p->ifa_next )
24783dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	{
24793dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		if( !p->ifa_addr || ( p->ifa_addr->sa_family != AF_INET ) || ( ( p->ifa_flags & flagMask ) != flagTest ) )
24803dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		{
24813dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			continue;
24823dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		}
24833dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		if( p->ifa_flags & IFF_LOOPBACK )
24843dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		{
24853dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			if( !loopbackv4 )
24863dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			{
24873dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin				loopbackv4 = p;
24883dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			}
24893dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			continue;
24903dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		}
24913dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		dlog( kDebugLevelVerbose, DEBUG_NAME "Interface %40s (0x%08X) %##a\n",
24923dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			p->ifa_name ? p->ifa_name : "<null>", p->ifa_extra.index, p->ifa_addr );
24933dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
24943dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		err = SetupInterface( inMDNS, p, &ifd );
24953dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		require_noerr( err, exit );
24963dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
24973dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		// If this guy is point-to-point (ifd->interfaceInfo.McastTxRx == 0 ) we still want to
24983dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		// register him, but we also want to note that we haven't found a v4 interface
24993dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		// so that we register loopback so same host operations work
25003dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
25013dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		if ( ifd->interfaceInfo.McastTxRx == mDNStrue )
25023dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		{
25033dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			foundv4 = mDNStrue;
25043dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		}
25053dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
25063dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		if ( p->ifa_dhcpEnabled && ( p->ifa_dhcpLeaseExpires < inMDNS->p->nextDHCPLeaseExpires ) )
25073dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		{
25083dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			inMDNS->p->nextDHCPLeaseExpires = p->ifa_dhcpLeaseExpires;
25093dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		}
25103dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
25113dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		// If we're on a platform that doesn't have WSARecvMsg(), there's no way
25123dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		// of determing the destination address of a packet that is sent to us.
25133dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		// For multicast packets, that's easy to determine.  But for the unicast
25143dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		// sockets, we'll fake it by taking the address of the first interface
25153dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		// that is successfully setup.
25163dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
25173dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		if ( !foundUnicastSock4DestAddr )
25183dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		{
25193dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			inMDNS->p->unicastSock4.addr = ifd->interfaceInfo.ip;
25203dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			foundUnicastSock4DestAddr = TRUE;
25213dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		}
25223dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
25233dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		*next = ifd;
25243dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		next  = &ifd->next;
25253dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		++inMDNS->p->interfaceCount;
25263dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	}
25273dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin#endif
25283dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
25293dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	// Set up IPv6 interface(s) after IPv4 is set up (see IPv4 notes above for reasoning).
25303dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
25313dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin#if( MDNS_WINDOWS_ENABLE_IPV6 )
25323dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	for( p = addrs; p; p = p->ifa_next )
25333dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	{
25343dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		if( !p->ifa_addr || ( p->ifa_addr->sa_family != AF_INET6 ) || ( ( p->ifa_flags & flagMask ) != flagTest ) )
25353dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		{
25363dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			continue;
25373dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		}
25383dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		if( p->ifa_flags & IFF_LOOPBACK )
25393dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		{
25403dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			if( !loopbackv6 )
25413dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			{
25423dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin				loopbackv6 = p;
25433dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			}
25443dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			continue;
25453dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		}
25463dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		dlog( kDebugLevelVerbose, DEBUG_NAME "Interface %40s (0x%08X) %##a\n",
25473dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			p->ifa_name ? p->ifa_name : "<null>", p->ifa_extra.index, p->ifa_addr );
25483dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
25493dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		err = SetupInterface( inMDNS, p, &ifd );
25503dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		require_noerr( err, exit );
25513dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
25523dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		// If this guy is point-to-point (ifd->interfaceInfo.McastTxRx == 0 ) we still want to
25533dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		// register him, but we also want to note that we haven't found a v4 interface
25543dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		// so that we register loopback so same host operations work
25553dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
25563dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		if ( ifd->interfaceInfo.McastTxRx == mDNStrue )
25573dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		{
25583dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			foundv6 = mDNStrue;
25593dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		}
25603dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
25613dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		// If we're on a platform that doesn't have WSARecvMsg(), there's no way
25623dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		// of determing the destination address of a packet that is sent to us.
25633dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		// For multicast packets, that's easy to determine.  But for the unicast
25643dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		// sockets, we'll fake it by taking the address of the first interface
25653dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		// that is successfully setup.
25663dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
25673dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		if ( !foundUnicastSock6DestAddr )
25683dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		{
25693dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			inMDNS->p->unicastSock6.addr = ifd->interfaceInfo.ip;
25703dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			foundUnicastSock6DestAddr = TRUE;
25713dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		}
25723dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
25733dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		*next = ifd;
25743dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		next  = &ifd->next;
25753dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		++inMDNS->p->interfaceCount;
25763dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	}
25773dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin#endif
25783dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
25793dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	// If there are no real interfaces, but there is a loopback interface, use that so same-machine operations work.
25803dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
25813dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin#if( !MDNS_WINDOWS_ENABLE_IPV4 && !MDNS_WINDOWS_ENABLE_IPV6 )
25823dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
25833dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	flagMask |= IFF_LOOPBACK;
25843dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	flagTest |= IFF_LOOPBACK;
25853dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
25863dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	for( p = addrs; p; p = p->ifa_next )
25873dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	{
25883dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		if( !p->ifa_addr || ( ( p->ifa_flags & flagMask ) != flagTest ) )
25893dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		{
25903dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			continue;
25913dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		}
25923dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		if( ( p->ifa_addr->sa_family != AF_INET ) && ( p->ifa_addr->sa_family != AF_INET6 ) )
25933dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		{
25943dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			continue;
25953dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		}
25963dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
25973dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		v4loopback = p;
25983dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		break;
25993dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	}
26003dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
26013dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin#endif
26023dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
26033dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	if ( !foundv4 && loopbackv4 )
26043dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	{
26053dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		dlog( kDebugLevelInfo, DEBUG_NAME "Interface %40s (0x%08X) %##a\n",
26063dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			loopbackv4->ifa_name ? loopbackv4->ifa_name : "<null>", loopbackv4->ifa_extra.index, loopbackv4->ifa_addr );
26073dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
26083dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		err = SetupInterface( inMDNS, loopbackv4, &ifd );
26093dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		require_noerr( err, exit );
26103dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
26113dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		inMDNS->p->registeredLoopback4 = mDNStrue;
26123dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
26133dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin#if( MDNS_WINDOWS_ENABLE_IPV4 )
26143dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
26153dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		// If we're on a platform that doesn't have WSARecvMsg(), there's no way
26163dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		// of determing the destination address of a packet that is sent to us.
26173dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		// For multicast packets, that's easy to determine.  But for the unicast
26183dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		// sockets, we'll fake it by taking the address of the first interface
26193dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		// that is successfully setup.
26203dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
26213dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		if ( !foundUnicastSock4DestAddr )
26223dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		{
26233dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			inMDNS->p->unicastSock4.addr = ifd->sock.addr;
26243dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			foundUnicastSock4DestAddr = TRUE;
26253dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		}
26263dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin#endif
26273dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
26283dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		*next = ifd;
26293dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		next  = &ifd->next;
26303dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		++inMDNS->p->interfaceCount;
26313dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	}
26323dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
26333dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	if ( !foundv6 && loopbackv6 )
26343dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	{
26353dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		dlog( kDebugLevelInfo, DEBUG_NAME "Interface %40s (0x%08X) %##a\n",
26363dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			loopbackv6->ifa_name ? loopbackv6->ifa_name : "<null>", loopbackv6->ifa_extra.index, loopbackv6->ifa_addr );
26373dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
26383dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		err = SetupInterface( inMDNS, loopbackv6, &ifd );
26393dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		require_noerr( err, exit );
26403dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
26413dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin#if( MDNS_WINDOWS_ENABLE_IPV6 )
26423dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
26433dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		// If we're on a platform that doesn't have WSARecvMsg(), there's no way
26443dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		// of determing the destination address of a packet that is sent to us.
26453dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		// For multicast packets, that's easy to determine.  But for the unicast
26463dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		// sockets, we'll fake it by taking the address of the first interface
26473dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		// that is successfully setup.
26483dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
26493dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		if ( !foundUnicastSock6DestAddr )
26503dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		{
26513dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			inMDNS->p->unicastSock6.addr = ifd->sock.addr;
26523dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			foundUnicastSock6DestAddr = TRUE;
26533dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		}
26543dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin#endif
26553dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
26563dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		*next = ifd;
26573dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		next  = &ifd->next;
26583dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		++inMDNS->p->interfaceCount;
26593dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	}
26603dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
26613dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	CheckFileShares( inMDNS );
26623dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
26633dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlinexit:
26643dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	if( err )
26653dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	{
26663dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		TearDownInterfaceList( inMDNS );
26673dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	}
26683dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	if( addrs )
26693dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	{
26703dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		freeifaddrs( addrs );
26713dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	}
26723dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	dlog( kDebugLevelTrace, DEBUG_NAME "setting up interface list done (err=%d %m)\n", err, err );
26733dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	return( err );
26743dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin}
26753dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
26763dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//===========================================================================================================================
26773dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//	TearDownInterfaceList
26783dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//===========================================================================================================================
26793dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
26803dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinmStatus	TearDownInterfaceList( mDNS * const inMDNS )
26813dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin{
26823dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	mDNSInterfaceData **		p;
26833dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	mDNSInterfaceData *		ifd;
26843dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
26853dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	dlog( kDebugLevelTrace, DEBUG_NAME "tearing down interface list\n" );
26863dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	check( inMDNS );
26873dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	check( inMDNS->p );
26883dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
26893dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	// Free any interfaces that were previously marked inactive and are no longer referenced by the mDNS cache.
26903dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	// Interfaces are marked inactive, but not deleted immediately if they were still referenced by the mDNS cache
26913dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	// so that remove events that occur after an interface goes away can still report the correct interface.
26923dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
26933dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	p = &inMDNS->p->inactiveInterfaceList;
26943dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	while( *p )
26953dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	{
26963dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		ifd = *p;
26973dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		if( NumCacheRecordsForInterfaceID( inMDNS, (mDNSInterfaceID) ifd ) > 0 )
26983dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		{
26993dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			p = &ifd->next;
27003dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			continue;
27013dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		}
27023dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
27033dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		dlog( kDebugLevelInfo, DEBUG_NAME "freeing unreferenced, inactive interface %#p %#a\n", ifd, &ifd->interfaceInfo.ip );
27043dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		*p = ifd->next;
27053dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
27063dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		QueueUserAPC( ( PAPCFUNC ) FreeInterface, inMDNS->p->mainThread, ( ULONG_PTR ) ifd );
27073dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	}
27083dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
27093dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	// Tear down all the interfaces.
27103dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
27113dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	while( inMDNS->p->interfaceList )
27123dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	{
27133dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		ifd = inMDNS->p->interfaceList;
27143dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		inMDNS->p->interfaceList = ifd->next;
27153dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
27163dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		TearDownInterface( inMDNS, ifd );
27173dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	}
27183dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	inMDNS->p->interfaceCount = 0;
27193dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
27203dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	dlog( kDebugLevelTrace, DEBUG_NAME "tearing down interface list done\n" );
27213dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	return( mStatus_NoError );
27223dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin}
27233dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
27243dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//===========================================================================================================================
27253dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//	SetupInterface
27263dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//===========================================================================================================================
27273dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
27283dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinmDNSlocal mStatus	SetupInterface( mDNS * const inMDNS, const struct ifaddrs *inIFA, mDNSInterfaceData **outIFD )
27293dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin{
27303dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	mDNSInterfaceData	*	ifd;
27313dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	mDNSInterfaceData	*	p;
27323dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	mStatus					err;
27333dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
27343dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	ifd = NULL;
27353dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	dlog( kDebugLevelTrace, DEBUG_NAME "setting up interface\n" );
27363dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	check( inMDNS );
27373dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	check( inMDNS->p );
27383dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	check( inIFA );
27393dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	check( inIFA->ifa_addr );
27403dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	check( outIFD );
27413dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
27423dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	// Allocate memory for the interface and initialize it.
27433dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
27443dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	ifd = (mDNSInterfaceData *) calloc( 1, sizeof( *ifd ) );
27453dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	require_action( ifd, exit, err = mStatus_NoMemoryErr );
27463dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	ifd->sock.fd		= kInvalidSocketRef;
27473dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	ifd->sock.overlapped.pending = FALSE;
27483dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	ifd->sock.ifd		= ifd;
27493dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	ifd->sock.next		= NULL;
27503dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	ifd->sock.m			= inMDNS;
27513dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	ifd->index			= inIFA->ifa_extra.index;
27523dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	ifd->scopeID		= inIFA->ifa_extra.index;
27533dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	check( strlen( inIFA->ifa_name ) < sizeof( ifd->name ) );
27543dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	strncpy( ifd->name, inIFA->ifa_name, sizeof( ifd->name ) - 1 );
27553dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	ifd->name[ sizeof( ifd->name ) - 1 ] = '\0';
27563dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
27573dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	strncpy(ifd->interfaceInfo.ifname, inIFA->ifa_name, sizeof(ifd->interfaceInfo.ifname));
27583dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	ifd->interfaceInfo.ifname[sizeof(ifd->interfaceInfo.ifname)-1] = 0;
27593dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
27603dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	// We always send and receive using IPv4, but to reduce traffic, we send and receive using IPv6 only on interfaces
27613dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	// that have no routable IPv4 address. Having a routable IPv4 address assigned is a reasonable indicator of being
27623dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	// on a large configured network, which means there's a good chance that most or all the other devices on that
27633dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	// network should also have v4. By doing this we lose the ability to talk to true v6-only devices on that link,
27643dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	// but we cut the packet rate in half. At this time, reducing the packet rate is more important than v6-only
27653dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	// devices on a large configured network, so we are willing to make that sacrifice.
27663dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
27673dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	ifd->interfaceInfo.McastTxRx   = ( ( inIFA->ifa_flags & IFF_MULTICAST ) && !( inIFA->ifa_flags & IFF_POINTTOPOINT ) ) ? mDNStrue : mDNSfalse;
27683dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	ifd->interfaceInfo.InterfaceID = NULL;
27693dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
27703dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	for( p = inMDNS->p->interfaceList; p; p = p->next )
27713dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	{
27723dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		if ( strcmp( p->name, ifd->name ) == 0 )
27733dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		{
27743dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			if (!ifd->interfaceInfo.InterfaceID)
27753dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			{
27763dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin				ifd->interfaceInfo.InterfaceID	= (mDNSInterfaceID) p;
27773dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			}
27783dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
27793dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			if ( ( inIFA->ifa_addr->sa_family != AF_INET ) &&
27803dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			     ( p->interfaceInfo.ip.type == mDNSAddrType_IPv4 ) &&
27813dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			     ( p->interfaceInfo.ip.ip.v4.b[ 0 ] != 169 || p->interfaceInfo.ip.ip.v4.b[ 1 ] != 254 ) )
27823dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			{
27833dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin				ifd->interfaceInfo.McastTxRx = mDNSfalse;
27843dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			}
27853dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
27863dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			break;
27873dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		}
27883dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	}
27893dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
27903dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	if ( !ifd->interfaceInfo.InterfaceID )
27913dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	{
27923dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		ifd->interfaceInfo.InterfaceID = (mDNSInterfaceID) ifd;
27933dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	}
27943dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
27953dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	// Set up a socket for this interface (if needed).
27963dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
27973dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	if( ifd->interfaceInfo.McastTxRx )
27983dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	{
27993dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		DWORD size;
28003dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
28013dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		err = SetupSocket( inMDNS, inIFA->ifa_addr, MulticastDNSPort, &ifd->sock.fd );
28023dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		require_noerr( err, exit );
28033dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		ifd->sock.addr = ( inIFA->ifa_addr->sa_family == AF_INET6 ) ? AllDNSLinkGroup_v6 : AllDNSLinkGroup_v4;
28043dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		ifd->sock.port = MulticastDNSPort;
28053dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
28063dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		// Get a ptr to the WSARecvMsg function, if supported. Otherwise, we'll fallback to recvfrom.
28073dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
28083dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		err = WSAIoctl( ifd->sock.fd, SIO_GET_EXTENSION_FUNCTION_POINTER, &kWSARecvMsgGUID, sizeof( kWSARecvMsgGUID ), &ifd->sock.recvMsgPtr, sizeof( ifd->sock.recvMsgPtr ), &size, NULL, NULL );
28093dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
28103dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		if ( err )
28113dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		{
28123dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			ifd->sock.recvMsgPtr = NULL;
28133dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		}
28143dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	}
28153dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
28163dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	if ( inIFA->ifa_dhcpEnabled && ( inIFA->ifa_dhcpLeaseExpires < inMDNS->p->nextDHCPLeaseExpires ) )
28173dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	{
28183dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		inMDNS->p->nextDHCPLeaseExpires = inIFA->ifa_dhcpLeaseExpires;
28193dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	}
28203dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
28213dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	ifd->interfaceInfo.NetWake = inIFA->ifa_womp;
28223dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
28233dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	// Register this interface with mDNS.
28243dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
28253dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	err = SockAddrToMDNSAddr( inIFA->ifa_addr, &ifd->interfaceInfo.ip, NULL );
28263dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	require_noerr( err, exit );
28273dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
28283dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	err = SockAddrToMDNSAddr( inIFA->ifa_netmask, &ifd->interfaceInfo.mask, NULL );
28293dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	require_noerr( err, exit );
28303dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
28313dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	memcpy( ifd->interfaceInfo.MAC.b, inIFA->ifa_physaddr, sizeof( ifd->interfaceInfo.MAC.b ) );
28323dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
28333dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	ifd->interfaceInfo.Advertise = ( mDNSu8 ) inMDNS->AdvertiseLocalAddresses;
28343dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
28353dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	if ( ifd->sock.fd != kInvalidSocketRef )
28363dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	{
28373dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		err = UDPBeginRecv( &ifd->sock );
28383dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		require_noerr( err, exit );
28393dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	}
28403dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
28413dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	err = mDNS_RegisterInterface( inMDNS, &ifd->interfaceInfo, mDNSfalse );
28423dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	require_noerr( err, exit );
28433dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	ifd->hostRegistered = mDNStrue;
28443dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
28453dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	dlog( kDebugLevelInfo, DEBUG_NAME "Registered interface %##a with mDNS\n", inIFA->ifa_addr );
28463dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
28473dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	// Success!
28483dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
28493dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	*outIFD = ifd;
28503dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	ifd = NULL;
28513dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
28523dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlinexit:
28533dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
28543dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	if( ifd )
28553dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	{
28563dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		TearDownInterface( inMDNS, ifd );
28573dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	}
28583dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	dlog( kDebugLevelTrace, DEBUG_NAME "setting up interface done (err=%d %m)\n", err, err );
28593dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	return( err );
28603dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin}
28613dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
28623dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//===========================================================================================================================
28633dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//	TearDownInterface
28643dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//===========================================================================================================================
28653dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
28663dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinmDNSlocal mStatus	TearDownInterface( mDNS * const inMDNS, mDNSInterfaceData *inIFD )
28673dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin{
28683dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	check( inMDNS );
28693dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	check( inIFD );
28703dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
28713dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	// Deregister this interface with mDNS.
28723dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
28733dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	dlog( kDebugLevelInfo, DEBUG_NAME "Deregistering interface %#a with mDNS\n", &inIFD->interfaceInfo.ip );
28743dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
28753dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	if( inIFD->hostRegistered )
28763dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	{
28773dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		inIFD->hostRegistered = mDNSfalse;
28783dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		mDNS_DeregisterInterface( inMDNS, &inIFD->interfaceInfo, mDNSfalse );
28793dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	}
28803dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
28813dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	// Tear down the multicast socket.
28823dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
28833dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	UDPCloseSocket( &inIFD->sock );
28843dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
28853dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	// If the interface is still referenced by items in the mDNS cache then put it on the inactive list. This keeps
28863dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	// the InterfaceID valid so remove events report the correct interface. If it is no longer referenced, free it.
28873dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
28883dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	if( NumCacheRecordsForInterfaceID( inMDNS, (mDNSInterfaceID) inIFD ) > 0 )
28893dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	{
28903dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		inIFD->next = inMDNS->p->inactiveInterfaceList;
28913dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		inMDNS->p->inactiveInterfaceList = inIFD;
28923dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		dlog( kDebugLevelInfo, DEBUG_NAME "deferring free of interface %#p %#a\n", inIFD, &inIFD->interfaceInfo.ip );
28933dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	}
28943dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	else
28953dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	{
28963dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		dlog( kDebugLevelInfo, DEBUG_NAME "freeing interface %#p %#a immediately\n", inIFD, &inIFD->interfaceInfo.ip );
28973dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		QueueUserAPC( ( PAPCFUNC ) FreeInterface, inMDNS->p->mainThread, ( ULONG_PTR ) inIFD );
28983dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	}
28993dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
29003dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	return( mStatus_NoError );
29013dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin}
29023dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
29033dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinmDNSlocal void CALLBACK FreeInterface( mDNSInterfaceData *inIFD )
29043dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin{
29053dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	free( inIFD );
29063dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin}
29073dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
29083dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//===========================================================================================================================
29093dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//	SetupSocket
29103dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//===========================================================================================================================
29113dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
29123dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinmDNSlocal mStatus	SetupSocket( mDNS * const inMDNS, const struct sockaddr *inAddr, mDNSIPPort port, SocketRef *outSocketRef  )
29133dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin{
29143dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	mStatus			err;
29153dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	SocketRef		sock;
29163dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	int				option;
29173dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	DWORD			bytesReturned = 0;
29183dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	BOOL			behavior = FALSE;
29193dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
29203dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	DEBUG_UNUSED( inMDNS );
29213dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
29223dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	dlog( kDebugLevelTrace, DEBUG_NAME "setting up socket %##a\n", inAddr );
29233dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	check( inMDNS );
29243dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	check( outSocketRef );
29253dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
29263dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	// Set up an IPv4 or IPv6 UDP socket.
29273dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
29283dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	sock = socket( inAddr->sa_family, SOCK_DGRAM, IPPROTO_UDP );
29293dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	err = translate_errno( IsValidSocket( sock ), errno_compat(), kUnknownErr );
29303dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	require_noerr( err, exit );
29313dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
29323dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	// Turn on reuse address option so multiple servers can listen for Multicast DNS packets,
29333dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	// if we're creating a multicast socket
29343dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
29353dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	if ( port.NotAnInteger )
29363dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	{
29373dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		option = 1;
29383dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		err = setsockopt( sock, SOL_SOCKET, SO_REUSEADDR, (char *) &option, sizeof( option ) );
29393dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		check_translated_errno( err == 0, errno_compat(), kOptionErr );
29403dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	}
29413dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
29423dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	// <rdar://problem/7894393> Bonjour for Windows broken on Windows XP
29433dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	//
29443dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	// Not sure why, but the default behavior for sockets is to behave incorrectly
29453dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	// when using them in Overlapped I/O mode on XP. According to MSDN:
29463dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	//
29473dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	// SIO_UDP_CONNRESET (opcode setting: I, T==3)
29483dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	//     Windows XP:  Controls whether UDP PORT_UNREACHABLE messages are reported. Set to TRUE to enable reporting.
29493dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	//     Set to FALSE to disable reporting.
29503dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	//
29513dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	// Packet traces from misbehaving Bonjour installations showed that ICMP port unreachable
29523dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	// messages were being sent to us after we sent out packets to a multicast address. This is clearly
29533dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	// incorrect behavior, but should be harmless. However, after receiving a port unreachable error, WinSock
29543dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	// will no longer receive any packets from that socket, which is not harmless. This behavior is only
29553dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	// seen on XP.
29563dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	//
29573dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	// So we turn off port unreachable reporting to make sure our sockets that are reading
29583dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	// multicast packets function correctly under all circumstances.
29593dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
29603dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	err = WSAIoctl( sock, SIO_UDP_CONNRESET, &behavior, sizeof(behavior), NULL, 0, &bytesReturned, NULL, NULL );
29613dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	check_translated_errno( err == 0, errno_compat(), kOptionErr );
29623dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
29633dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	if( inAddr->sa_family == AF_INET )
29643dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	{
29653dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		mDNSv4Addr				ipv4;
29663dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		struct sockaddr_in		sa4;
29673dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		struct ip_mreq			mreqv4;
29683dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
29693dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		// Bind the socket to the desired port
29703dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
29713dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		ipv4.NotAnInteger 	= ( (const struct sockaddr_in *) inAddr )->sin_addr.s_addr;
29723dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		mDNSPlatformMemZero( &sa4, sizeof( sa4 ) );
29733dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		sa4.sin_family 		= AF_INET;
29743dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		sa4.sin_port 		= port.NotAnInteger;
29753dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		sa4.sin_addr.s_addr	= ipv4.NotAnInteger;
29763dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
29773dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		err = bind( sock, (struct sockaddr *) &sa4, sizeof( sa4 ) );
29783dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		check_translated_errno( err == 0, errno_compat(), kUnknownErr );
29793dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
29803dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		// Turn on option to receive destination addresses and receiving interface.
29813dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
29823dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		option = 1;
29833dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		err = setsockopt( sock, IPPROTO_IP, IP_PKTINFO, (char *) &option, sizeof( option ) );
29843dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		check_translated_errno( err == 0, errno_compat(), kOptionErr );
29853dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
29863dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		if (port.NotAnInteger)
29873dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		{
29883dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			// Join the all-DNS multicast group so we receive Multicast DNS packets
29893dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
29903dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			mreqv4.imr_multiaddr.s_addr = AllDNSLinkGroup_v4.ip.v4.NotAnInteger;
29913dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			mreqv4.imr_interface.s_addr = ipv4.NotAnInteger;
29923dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			err = setsockopt( sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char *) &mreqv4, sizeof( mreqv4 ) );
29933dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			check_translated_errno( err == 0, errno_compat(), kOptionErr );
29943dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
29953dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			// Specify the interface to send multicast packets on this socket.
29963dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
29973dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			sa4.sin_addr.s_addr = ipv4.NotAnInteger;
29983dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			err = setsockopt( sock, IPPROTO_IP, IP_MULTICAST_IF, (char *) &sa4.sin_addr, sizeof( sa4.sin_addr ) );
29993dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			check_translated_errno( err == 0, errno_compat(), kOptionErr );
30003dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
30013dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			// Enable multicast loopback so we receive multicast packets we send (for same-machine operations).
30023dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
30033dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			option = 1;
30043dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			err = setsockopt( sock, IPPROTO_IP, IP_MULTICAST_LOOP, (char *) &option, sizeof( option ) );
30053dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			check_translated_errno( err == 0, errno_compat(), kOptionErr );
30063dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		}
30073dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
30083dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		// Send unicast packets with TTL 255 (helps against spoofing).
30093dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
30103dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		option = 255;
30113dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		err = setsockopt( sock, IPPROTO_IP, IP_TTL, (char *) &option, sizeof( option ) );
30123dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		check_translated_errno( err == 0, errno_compat(), kOptionErr );
30133dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
30143dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		// Send multicast packets with TTL 255 (helps against spoofing).
30153dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
30163dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		option = 255;
30173dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		err = setsockopt( sock, IPPROTO_IP, IP_MULTICAST_TTL, (char *) &option, sizeof( option ) );
30183dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		check_translated_errno( err == 0, errno_compat(), kOptionErr );
30193dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
30203dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	}
30213dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	else if( inAddr->sa_family == AF_INET6 )
30223dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	{
30233dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		struct sockaddr_in6 *		sa6p;
30243dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		struct sockaddr_in6			sa6;
30253dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		struct ipv6_mreq			mreqv6;
30263dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
30273dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		sa6p = (struct sockaddr_in6 *) inAddr;
30283dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
30293dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		// Bind the socket to the desired port
30303dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
30313dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		mDNSPlatformMemZero( &sa6, sizeof( sa6 ) );
30323dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		sa6.sin6_family		= AF_INET6;
30333dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		sa6.sin6_port		= port.NotAnInteger;
30343dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		sa6.sin6_flowinfo	= 0;
30353dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		sa6.sin6_addr		= sa6p->sin6_addr;
30363dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		sa6.sin6_scope_id	= sa6p->sin6_scope_id;
30373dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
30383dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		err = bind( sock, (struct sockaddr *) &sa6, sizeof( sa6 ) );
30393dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		check_translated_errno( err == 0, errno_compat(), kUnknownErr );
30403dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
30413dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		// Turn on option to receive destination addresses and receiving interface.
30423dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
30433dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		option = 1;
30443dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		err = setsockopt( sock, IPPROTO_IPV6, IPV6_PKTINFO, (char *) &option, sizeof( option ) );
30453dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		check_translated_errno( err == 0, errno_compat(), kOptionErr );
30463dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
30473dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		// We only want to receive IPv6 packets (not IPv4-mapped IPv6 addresses) because we have a separate socket
30483dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		// for IPv4, but the IPv6 stack in Windows currently doesn't support IPv4-mapped IPv6 addresses and doesn't
30493dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		// support the IPV6_V6ONLY socket option so the following code would typically not be executed (or needed).
30503dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
30513dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		#if( defined( IPV6_V6ONLY ) )
30523dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			option = 1;
30533dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			err = setsockopt( sock, IPPROTO_IPV6, IPV6_V6ONLY, (char *) &option, sizeof( option ) );
30543dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			check_translated_errno( err == 0, errno_compat(), kOptionErr );
30553dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		#endif
30563dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
30573dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		if ( port.NotAnInteger )
30583dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		{
30593dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			// Join the all-DNS multicast group so we receive Multicast DNS packets.
30603dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
30613dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			mreqv6.ipv6mr_multiaddr = *( (struct in6_addr *) &AllDNSLinkGroup_v6.ip.v6 );
30623dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			mreqv6.ipv6mr_interface = sa6p->sin6_scope_id;
30633dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			err = setsockopt( sock, IPPROTO_IPV6, IPV6_JOIN_GROUP, (char *) &mreqv6, sizeof( mreqv6 ) );
30643dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			check_translated_errno( err == 0, errno_compat(), kOptionErr );
30653dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
30663dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			// Specify the interface to send multicast packets on this socket.
30673dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
30683dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			option = (int) sa6p->sin6_scope_id;
30693dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			err = setsockopt( sock, IPPROTO_IPV6, IPV6_MULTICAST_IF, (char *) &option, sizeof( option ) );
30703dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			check_translated_errno( err == 0, errno_compat(), kOptionErr );
30713dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
30723dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			// Enable multicast loopback so we receive multicast packets we send (for same-machine operations).
30733dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
30743dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			option = 1;
30753dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			err = setsockopt( sock, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, (char *) &option, sizeof( option ) );
30763dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			check_translated_errno( err == 0, errno_compat(), kOptionErr );
30773dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		}
30783dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
30793dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		// Send unicast packets with TTL 255 (helps against spoofing).
30803dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
30813dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		option = 255;
30823dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		err = setsockopt( sock, IPPROTO_IPV6, IPV6_UNICAST_HOPS, (char *) &option, sizeof( option ) );
30833dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		check_translated_errno( err == 0, errno_compat(), kOptionErr );
30843dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
30853dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		// Send multicast packets with TTL 255 (helps against spoofing).
30863dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
30873dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		option = 255;
30883dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		err = setsockopt( sock, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, (char *) &option, sizeof( option ) );
30893dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		check_translated_errno( err == 0, errno_compat(), kOptionErr );
30903dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	}
30913dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	else
30923dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	{
30933dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		dlog( kDebugLevelError, DEBUG_NAME "%s: unsupport socket family (%d)\n", __ROUTINE__, inAddr->sa_family );
30943dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		err = kUnsupportedErr;
30953dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		goto exit;
30963dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	}
30973dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
30983dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	// Success!
30993dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
31003dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	*outSocketRef = sock;
31013dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	sock = kInvalidSocketRef;
31023dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	err = mStatus_NoError;
31033dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
31043dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlinexit:
31053dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	if( IsValidSocket( sock ) )
31063dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	{
31073dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		close_compat( sock );
31083dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	}
31093dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	return( err );
31103dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin}
31113dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
31123dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//===========================================================================================================================
31133dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//	SetupSocket
31143dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//===========================================================================================================================
31153dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
31163dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinmDNSlocal mStatus	SockAddrToMDNSAddr( const struct sockaddr * const inSA, mDNSAddr *outIP, mDNSIPPort *outPort )
31173dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin{
31183dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	mStatus		err;
31193dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
31203dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	check( inSA );
31213dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	check( outIP );
31223dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
31233dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	if( inSA->sa_family == AF_INET )
31243dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	{
31253dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		struct sockaddr_in *		sa4;
31263dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
31273dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		sa4 						= (struct sockaddr_in *) inSA;
31283dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		outIP->type 				= mDNSAddrType_IPv4;
31293dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		outIP->ip.v4.NotAnInteger	= sa4->sin_addr.s_addr;
31303dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		if( outPort )
31313dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		{
31323dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			outPort->NotAnInteger	= sa4->sin_port;
31333dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		}
31343dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		err = mStatus_NoError;
31353dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	}
31363dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	else if( inSA->sa_family == AF_INET6 )
31373dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	{
31383dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		struct sockaddr_in6 *		sa6;
31393dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
31403dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		sa6 			= (struct sockaddr_in6 *) inSA;
31413dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		outIP->type 	= mDNSAddrType_IPv6;
31423dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		outIP->ip.v6 	= *( (mDNSv6Addr *) &sa6->sin6_addr );
31433dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		if( IN6_IS_ADDR_LINKLOCAL( &sa6->sin6_addr ) )
31443dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		{
31453dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			outIP->ip.v6.w[ 1 ] = 0;
31463dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		}
31473dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		if( outPort )
31483dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		{
31493dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			outPort->NotAnInteger = sa6->sin6_port;
31503dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		}
31513dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		err = mStatus_NoError;
31523dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	}
31533dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	else
31543dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	{
31553dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		dlog( kDebugLevelError, DEBUG_NAME "%s: invalid sa_family %d", __ROUTINE__, inSA->sa_family );
31563dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		err = mStatus_BadParamErr;
31573dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	}
31583dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	return( err );
31593dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin}
31603dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
31613dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
31623dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin#if 0
31633dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin#pragma mark -
31643dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin#endif
31653dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
31663dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//===========================================================================================================================
31673dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//	UDPBeginRecv
31683dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//===========================================================================================================================
31693dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
31703dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinmDNSlocal OSStatus UDPBeginRecv( UDPSocket * sock )
31713dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin{
31723dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	DWORD	size;
31733dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	DWORD	numTries;
31743dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	mStatus	err;
31753dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
31763dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	dlog( kDebugLevelChatty, DEBUG_NAME "%s: sock = %d\n", __ROUTINE__, sock->fd );
31773dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
31783dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	require_action( sock != NULL, exit, err = mStatus_BadStateErr );
31793dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	check( !sock->overlapped.pending );
31803dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
31813dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	// Initialize the buffer structure
31823dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
31833dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	sock->overlapped.wbuf.buf	= (char *) &sock->packet;
31843dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	sock->overlapped.wbuf.len	= (u_long) sizeof( sock->packet );
31853dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	sock->srcAddrLen			= sizeof( sock->srcAddr );
31863dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
31873dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	// Initialize the overlapped structure
31883dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
31893dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	ZeroMemory( &sock->overlapped.data, sizeof( OVERLAPPED ) );
31903dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	sock->overlapped.data.hEvent = sock;
31913dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
31923dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	numTries = 0;
31933dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
31943dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	do
31953dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	{
31963dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		if ( sock->recvMsgPtr )
31973dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		{
31983dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			sock->wmsg.name				= ( LPSOCKADDR ) &sock->srcAddr;
31993dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			sock->wmsg.namelen			= sock->srcAddrLen;
32003dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			sock->wmsg.lpBuffers		= &sock->overlapped.wbuf;
32013dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			sock->wmsg.dwBufferCount	= 1;
32023dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			sock->wmsg.Control.buf		= ( CHAR* ) sock->controlBuffer;
32033dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			sock->wmsg.Control.len		= sizeof( sock->controlBuffer );
32043dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			sock->wmsg.dwFlags			= 0;
32053dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
32063dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			err = sock->recvMsgPtr( sock->fd, &sock->wmsg, &size, &sock->overlapped.data, ( LPWSAOVERLAPPED_COMPLETION_ROUTINE ) UDPEndRecv );
32073dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			err = translate_errno( ( err == 0 ) || ( WSAGetLastError() == WSA_IO_PENDING ), (OSStatus) WSAGetLastError(), kUnknownErr );
32083dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
32093dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			// <rdar://problem/7824093> iTunes 9.1 fails to install with Bonjour service on Windows 7 Ultimate
32103dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			//
32113dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			// There seems to be a bug in some network device drivers that involves calling WSARecvMsg() in
32123dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			// overlapped i/o mode. Although all the parameters to WSARecvMsg() are correct, it returns a
32133dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			// WSAEFAULT error code when there is no actual error. We have found experientially that falling
32143dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			// back to using WSARecvFrom() when this happens will work correctly.
32153dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
32163dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			if ( err == WSAEFAULT ) sock->recvMsgPtr = NULL;
32173dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		}
32183dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		else
32193dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		{
32203dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			DWORD flags = 0;
32213dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
32223dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			err = WSARecvFrom( sock->fd, &sock->overlapped.wbuf, 1, NULL, &flags, ( LPSOCKADDR ) &sock->srcAddr, &sock->srcAddrLen, &sock->overlapped.data, ( LPWSAOVERLAPPED_COMPLETION_ROUTINE ) UDPEndRecv );
32233dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			err = translate_errno( ( err == 0 ) || ( WSAGetLastError() == WSA_IO_PENDING ), ( OSStatus ) WSAGetLastError(), kUnknownErr );
32243dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		}
32253dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
32263dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		// According to MSDN <http://msdn.microsoft.com/en-us/library/ms741687(VS.85).aspx>:
32273dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		//
32283dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		// "WSAECONNRESET: For a UDP datagram socket, this error would indicate that a previous
32293dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		//                 send operation resulted in an ICMP "Port Unreachable" message."
32303dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		//
32313dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		// Because this is the case, we want to ignore this error and try again.  Just in case
32323dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		// this is some kind of pathological condition, we'll break out of the retry loop
32333dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		// after 100 iterations
32343dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
32353dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		require_action( !err || ( err == WSAECONNRESET ) || ( err == WSAEFAULT ), exit, err = WSAGetLastError() );
32363dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	}
32373dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	while ( ( ( err == WSAECONNRESET ) || ( err == WSAEFAULT ) ) && ( numTries++ < 100 ) );
32383dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
32393dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	sock->overlapped.pending = TRUE;
32403dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
32413dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlinexit:
32423dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
32433dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	if ( err )
32443dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	{
32453dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		LogMsg( "WSARecvMsg failed (%d)\n", err );
32463dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	}
32473dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
32483dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	return err;
32493dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin}
32503dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
32513dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
32523dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//===========================================================================================================================
32533dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//	UDPEndRecv
32543dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//===========================================================================================================================
32553dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
32563dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinmDNSlocal void CALLBACK UDPEndRecv( DWORD err, DWORD bytesTransferred, LPWSAOVERLAPPED overlapped, DWORD flags )
32573dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin{
32583dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	UDPSocket * sock = NULL;
32593dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
32603dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	( void ) flags;
32613dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
32623dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	dlog( kDebugLevelChatty, DEBUG_NAME "%s: err = %d, bytesTransferred = %d\n", __ROUTINE__, err, bytesTransferred );
32633dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	require_action_quiet( err != WSA_OPERATION_ABORTED, exit, err = ( DWORD ) kUnknownErr );
32643dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	require_noerr( err, exit );
32653dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	sock = ( overlapped != NULL ) ? overlapped->hEvent : NULL;
32663dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	require_action( sock != NULL, exit, err = ( DWORD ) kUnknownErr );
32673dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	dlog( kDebugLevelChatty, DEBUG_NAME "%s: sock = %d\n", __ROUTINE__, sock->fd );
32683dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	sock->overlapped.error				= err;
32693dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	sock->overlapped.bytesTransferred	= bytesTransferred;
32703dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	check( sock->overlapped.pending );
32713dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	sock->overlapped.pending			= FALSE;
32723dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
32733dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	// Translate the source of this packet into mDNS data types
32743dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
32753dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	SockAddrToMDNSAddr( (struct sockaddr *) &sock->srcAddr, &sock->overlapped.srcAddr, &sock->overlapped.srcPort );
32763dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
32773dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	// Initialize the destination of this packet. Just in case
32783dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	// we can't determine this info because we couldn't call
32793dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	// WSARecvMsg (recvMsgPtr)
32803dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
32813dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	sock->overlapped.dstAddr = sock->addr;
32823dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	sock->overlapped.dstPort = sock->port;
32833dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
32843dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	if ( sock->recvMsgPtr )
32853dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	{
32863dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		LPWSACMSGHDR	header;
32873dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		LPWSACMSGHDR	last = NULL;
32883dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		int				count = 0;
32893dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
32903dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		// Parse the control information. Reject packets received on the wrong interface.
32913dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
32923dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		// <rdar://problem/7832196> INSTALL: Bonjour 2.0 on Windows can not start / stop
32933dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		//
32943dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		// There seems to be an interaction between Bullguard and this next bit of code.
32953dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		// When a user's machine is running Bullguard, the control information that is
32963dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		// returned is corrupted, and the code would go into an infinite loop. We'll add
32973dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		// two bits of defensive coding here. The first will check that each pointer to
32983dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		// the LPWSACMSGHDR that is returned in the for loop is different than the last.
32993dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		// This fixes the problem with Bullguard. The second will break out of this loop
33003dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		// after 100 iterations, just in case the corruption isn't caught by the first
33013dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		// check.
33023dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
33033dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		for ( header = WSA_CMSG_FIRSTHDR( &sock->wmsg ); header; header = WSA_CMSG_NXTHDR( &sock->wmsg, header ) )
33043dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		{
33053dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			if ( ( header != last ) && ( ++count < 100 ) )
33063dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			{
33073dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin				last = header;
33083dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
33093dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin				if ( ( header->cmsg_level == IPPROTO_IP ) && ( header->cmsg_type == IP_PKTINFO ) )
33103dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin				{
33113dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin					IN_PKTINFO * ipv4PacketInfo;
33123dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
33133dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin					ipv4PacketInfo = (IN_PKTINFO *) WSA_CMSG_DATA( header );
33143dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
33153dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin					if ( sock->ifd != NULL )
33163dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin					{
33173dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin						require_action( ipv4PacketInfo->ipi_ifindex == sock->ifd->index, exit, err = ( DWORD ) kMismatchErr );
33183dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin					}
33193dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
33203dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin					sock->overlapped.dstAddr.type 				= mDNSAddrType_IPv4;
33213dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin					sock->overlapped.dstAddr.ip.v4.NotAnInteger	= ipv4PacketInfo->ipi_addr.s_addr;
33223dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin				}
33233dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin				else if( ( header->cmsg_level == IPPROTO_IPV6 ) && ( header->cmsg_type == IPV6_PKTINFO ) )
33243dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin				{
33253dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin					IN6_PKTINFO * ipv6PacketInfo;
33263dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
33273dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin					ipv6PacketInfo = (IN6_PKTINFO *) WSA_CMSG_DATA( header );
33283dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
33293dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin					if ( sock->ifd != NULL )
33303dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin					{
33313dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin						require_action( ipv6PacketInfo->ipi6_ifindex == ( sock->ifd->index - kIPv6IfIndexBase ), exit, err = ( DWORD ) kMismatchErr );
33323dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin					}
33333dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
33343dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin					sock->overlapped.dstAddr.type	= mDNSAddrType_IPv6;
33353dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin					sock->overlapped.dstAddr.ip.v6	= *( (mDNSv6Addr *) &ipv6PacketInfo->ipi6_addr );
33363dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin				}
33373dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			}
33383dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			else
33393dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			{
33403dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin				static BOOL loggedMessage = FALSE;
33413dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
33423dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin				if ( !loggedMessage )
33433dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin				{
33443dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin					LogMsg( "UDPEndRecv: WSARecvMsg control information error." );
33453dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin					loggedMessage = TRUE;
33463dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin				}
33473dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
33483dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin				break;
33493dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			}
33503dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		}
33513dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	}
33523dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
33533dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	dlog( kDebugLevelChatty, DEBUG_NAME "packet received\n" );
33543dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	dlog( kDebugLevelChatty, DEBUG_NAME "    size      = %d\n", bytesTransferred );
33553dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	dlog( kDebugLevelChatty, DEBUG_NAME "    src       = %#a:%u\n", &sock->overlapped.srcAddr, ntohs( sock->overlapped.srcPort.NotAnInteger ) );
33563dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	dlog( kDebugLevelChatty, DEBUG_NAME "    dst       = %#a:%u\n", &sock->overlapped.dstAddr, ntohs( sock->overlapped.dstPort.NotAnInteger ) );
33573dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
33583dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	if ( sock->ifd != NULL )
33593dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	{
33603dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		dlog( kDebugLevelChatty, DEBUG_NAME "    interface = %#a (index=0x%08X)\n", &sock->ifd->interfaceInfo.ip, sock->ifd->index );
33613dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	}
33623dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
33633dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	dlog( kDebugLevelChatty, DEBUG_NAME "\n" );
33643dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
33653dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	// Queue this socket
33663dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
33673dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	AddToTail( &gUDPDispatchableSockets, sock );
33683dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
33693dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlinexit:
33703dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
33713dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	return;
33723dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin}
33733dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
33743dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
33753dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//===========================================================================================================================
33763dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//	InterfaceListDidChange
33773dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//===========================================================================================================================
33783dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlinvoid InterfaceListDidChange( mDNS * const inMDNS )
33793dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin{
33803dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	mStatus err;
33813dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
33823dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	dlog( kDebugLevelInfo, DEBUG_NAME "interface list changed\n" );
33833dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	check( inMDNS );
33843dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
33853dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	// Tear down the existing interfaces and set up new ones using the new IP info.
33863dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
33873dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	err = TearDownInterfaceList( inMDNS );
33883dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	check_noerr( err );
33893dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
33903dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	err = SetupInterfaceList( inMDNS );
33913dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	check_noerr( err );
33923dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
33933dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	err = uDNS_SetupDNSConfig( inMDNS );
33943dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	check_noerr( err );
33953dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
33963dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	// Inform clients of the change.
33973dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
33983dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	mDNS_ConfigChanged(inMDNS);
33993dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
34003dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	// Force mDNS to update.
34013dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
34023dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	mDNSCoreMachineSleep( inMDNS, mDNSfalse ); // What is this for? Mac OS X does not do this
34033dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin}
34043dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
34053dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
34063dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//===========================================================================================================================
34073dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//	ComputerDescriptionDidChange
34083dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//===========================================================================================================================
34093dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlinvoid ComputerDescriptionDidChange( mDNS * const inMDNS )
34103dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin{
34113dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	dlog( kDebugLevelInfo, DEBUG_NAME "computer description has changed\n" );
34123dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	check( inMDNS );
34133dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
34143dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	// redo the names
34153dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	SetupNiceName( inMDNS );
34163dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin}
34173dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
34183dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
34193dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//===========================================================================================================================
34203dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//	TCPIPConfigDidChange
34213dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//===========================================================================================================================
34223dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlinvoid TCPIPConfigDidChange( mDNS * const inMDNS )
34233dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin{
34243dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	mStatus		err;
34253dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
34263dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	dlog( kDebugLevelInfo, DEBUG_NAME "TCP/IP config has changed\n" );
34273dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	check( inMDNS );
34283dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
34293dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	err = uDNS_SetupDNSConfig( inMDNS );
34303dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	check_noerr( err );
34313dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin}
34323dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
34333dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
34343dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//===========================================================================================================================
34353dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//	DynDNSConfigDidChange
34363dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//===========================================================================================================================
34373dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlinvoid DynDNSConfigDidChange( mDNS * const inMDNS )
34383dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin{
34393dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	mStatus		err;
34403dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
34413dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	dlog( kDebugLevelInfo, DEBUG_NAME "DynDNS config has changed\n" );
34423dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	check( inMDNS );
34433dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
34443dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	SetDomainSecrets( inMDNS );
34453dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
34463dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	err = uDNS_SetupDNSConfig( inMDNS );
34473dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	check_noerr( err );
34483dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin}
34493dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
34503dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
34513dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//===========================================================================================================================
34523dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//	FileSharingDidChange
34533dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//===========================================================================================================================
34543dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlinvoid FileSharingDidChange( mDNS * const inMDNS )
34553dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin{
34563dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	dlog( kDebugLevelInfo, DEBUG_NAME "File shares has changed\n" );
34573dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	check( inMDNS );
34583dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
34593dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	CheckFileShares( inMDNS );
34603dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin}
34613dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
34623dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
34633dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//===========================================================================================================================
34643dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//	FilewallDidChange
34653dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//===========================================================================================================================
34663dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlinvoid FirewallDidChange( mDNS * const inMDNS )
34673dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin{
34683dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	dlog( kDebugLevelInfo, DEBUG_NAME "Firewall has changed\n" );
34693dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	check( inMDNS );
34703dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
34713dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	CheckFileShares( inMDNS );
34723dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin}
34733dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
34743dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
34753dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin#if 0
34763dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin#pragma mark -
34773dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin#pragma mark == Utilities ==
34783dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin#endif
34793dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
34803dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//===========================================================================================================================
34813dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//	getifaddrs
34823dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//===========================================================================================================================
34833dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
34843dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinmDNSlocal int	getifaddrs( struct ifaddrs **outAddrs )
34853dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin{
34863dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	int		err;
34873dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
34883dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin#if( MDNS_WINDOWS_USE_IPV6_IF_ADDRS )
34893dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
34903dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	// Try to the load the GetAdaptersAddresses function from the IP Helpers DLL. This API is only available on Windows
34913dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	// XP or later. Looking up the symbol at runtime allows the code to still work on older systems without that API.
34923dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
34933dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	if( !gIPHelperLibraryInstance )
34943dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	{
34953dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		gIPHelperLibraryInstance = LoadLibrary( TEXT( "Iphlpapi" ) );
34963dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		if( gIPHelperLibraryInstance )
34973dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		{
34983dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			gGetAdaptersAddressesFunctionPtr =
34993dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin				(GetAdaptersAddressesFunctionPtr) GetProcAddress( gIPHelperLibraryInstance, "GetAdaptersAddresses" );
35003dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			if( !gGetAdaptersAddressesFunctionPtr )
35013dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			{
35023dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin				BOOL		ok;
35033dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
35043dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin				ok = FreeLibrary( gIPHelperLibraryInstance );
35053dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin				check_translated_errno( ok, GetLastError(), kUnknownErr );
35063dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin				gIPHelperLibraryInstance = NULL;
35073dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			}
35083dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		}
35093dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	}
35103dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
35113dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	// Use the new IPv6-capable routine if supported. Otherwise, fall back to the old and compatible IPv4-only code.
35123dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	// <rdar://problem/4278934>  Fall back to using getifaddrs_ipv4 if getifaddrs_ipv6 fails
35133dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	// <rdar://problem/6145913>  Fall back to using getifaddrs_ipv4 if getifaddrs_ipv6 returns no addrs
35143dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
35153dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	if( !gGetAdaptersAddressesFunctionPtr || ( ( ( err = getifaddrs_ipv6( outAddrs ) ) != mStatus_NoError ) || ( ( outAddrs != NULL ) && ( *outAddrs == NULL ) ) ) )
35163dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	{
35173dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		err = getifaddrs_ipv4( outAddrs );
35183dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		require_noerr( err, exit );
35193dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	}
35203dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
35213dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin#else
35223dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
35233dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	err = getifaddrs_ipv4( outAddrs );
35243dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	require_noerr( err, exit );
35253dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
35263dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin#endif
35273dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
35283dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlinexit:
35293dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	return( err );
35303dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin}
35313dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
35323dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin#if( MDNS_WINDOWS_USE_IPV6_IF_ADDRS )
35333dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//===========================================================================================================================
35343dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//	getifaddrs_ipv6
35353dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//===========================================================================================================================
35363dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
35373dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinmDNSlocal int	getifaddrs_ipv6( struct ifaddrs **outAddrs )
35383dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin{
35393dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	DWORD						err;
35403dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	int							i;
35413dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	DWORD						flags;
35423dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	struct ifaddrs *			head;
35433dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	struct ifaddrs **			next;
35443dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	IP_ADAPTER_ADDRESSES *		iaaList;
35453dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	ULONG						iaaListSize;
35463dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	IP_ADAPTER_ADDRESSES *		iaa;
35473dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	size_t						size;
35483dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	struct ifaddrs *			ifa;
35493dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
35503dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	check( gGetAdaptersAddressesFunctionPtr );
35513dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
35523dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	head	= NULL;
35533dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	next	= &head;
35543dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	iaaList	= NULL;
35553dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
35563dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	// Get the list of interfaces. The first call gets the size and the second call gets the actual data.
35573dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	// This loops to handle the case where the interface changes in the window after getting the size, but before the
35583dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	// second call completes. A limit of 100 retries is enforced to prevent infinite loops if something else is wrong.
35593dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
35603dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	flags = GAA_FLAG_INCLUDE_PREFIX | GAA_FLAG_SKIP_ANYCAST | GAA_FLAG_SKIP_MULTICAST | GAA_FLAG_SKIP_DNS_SERVER | GAA_FLAG_SKIP_FRIENDLY_NAME;
35613dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	i = 0;
35623dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	for( ;; )
35633dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	{
35643dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		iaaListSize = 0;
35653dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		err = gGetAdaptersAddressesFunctionPtr( AF_UNSPEC, flags, NULL, NULL, &iaaListSize );
35663dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		check( err == ERROR_BUFFER_OVERFLOW );
35673dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		check( iaaListSize >= sizeof( IP_ADAPTER_ADDRESSES ) );
35683dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
35693dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		iaaList = (IP_ADAPTER_ADDRESSES *) malloc( iaaListSize );
35703dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		require_action( iaaList, exit, err = ERROR_NOT_ENOUGH_MEMORY );
35713dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
35723dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		err = gGetAdaptersAddressesFunctionPtr( AF_UNSPEC, flags, NULL, iaaList, &iaaListSize );
35733dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		if( err == ERROR_SUCCESS ) break;
35743dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
35753dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		free( iaaList );
35763dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		iaaList = NULL;
35773dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		++i;
35783dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		require( i < 100, exit );
35793dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		dlog( kDebugLevelWarning, "%s: retrying GetAdaptersAddresses after %d failure(s) (%d %m)\n", __ROUTINE__, i, err, err );
35803dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	}
35813dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
35823dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	for( iaa = iaaList; iaa; iaa = iaa->Next )
35833dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	{
35843dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		int								addrIndex;
35853dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		IP_ADAPTER_UNICAST_ADDRESS	*	addr;
35863dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		DWORD							ipv6IfIndex;
35873dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		IP_ADAPTER_PREFIX			*	firstPrefix;
35883dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
35893dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		if( iaa->IfIndex > 0xFFFFFF )
35903dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		{
35913dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			dlog( kDebugLevelAlert, DEBUG_NAME "%s: IPv4 ifindex out-of-range (0x%08X)\n", __ROUTINE__, iaa->IfIndex );
35923dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		}
35933dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		if( iaa->Ipv6IfIndex > 0xFF )
35943dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		{
35953dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			dlog( kDebugLevelAlert, DEBUG_NAME "%s: IPv6 ifindex out-of-range (0x%08X)\n", __ROUTINE__, iaa->Ipv6IfIndex );
35963dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		}
35973dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
35983dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		// For IPv4 interfaces, there seems to be a bug in iphlpapi.dll that causes the
35993dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		// following code to crash when iterating through the prefix list.  This seems
36003dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		// to occur when iaa->Ipv6IfIndex != 0 when IPv6 is not installed on the host.
36013dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		// This shouldn't happen according to Microsoft docs which states:
36023dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		//
36033dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		//     "Ipv6IfIndex contains 0 if IPv6 is not available on the interface."
36043dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		//
36053dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		// So the data structure seems to be corrupted when we return from
36063dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		// GetAdaptersAddresses(). The bug seems to occur when iaa->Length <
36073dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		// sizeof(IP_ADAPTER_ADDRESSES), so when that happens, we'll manually
36083dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		// modify iaa to have the correct values.
36093dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
36103dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		if ( iaa->Length >= sizeof( IP_ADAPTER_ADDRESSES ) )
36113dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		{
36123dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			ipv6IfIndex = iaa->Ipv6IfIndex;
36133dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			firstPrefix = iaa->FirstPrefix;
36143dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		}
36153dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		else
36163dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		{
36173dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			ipv6IfIndex	= 0;
36183dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			firstPrefix = NULL;
36193dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		}
36203dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
36213dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		// Skip pseudo and tunnel interfaces.
36223dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
36233dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		if( ( ( ipv6IfIndex == 1 ) && ( iaa->IfType != IF_TYPE_SOFTWARE_LOOPBACK ) ) || ( iaa->IfType == IF_TYPE_TUNNEL ) )
36243dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		{
36253dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			continue;
36263dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		}
36273dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
36283dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		// Add each address as a separate interface to emulate the way getifaddrs works.
36293dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
36303dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		for( addrIndex = 0, addr = iaa->FirstUnicastAddress; addr; ++addrIndex, addr = addr->Next )
36313dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		{
36323dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			int						family;
36333dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			int						prefixIndex;
36343dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			IP_ADAPTER_PREFIX *		prefix;
36353dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			ULONG					prefixLength;
36363dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			uint32_t				ipv4Index;
36373dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			struct sockaddr_in		ipv4Netmask;
36383dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
36393dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			family = addr->Address.lpSockaddr->sa_family;
36403dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			if( ( family != AF_INET ) && ( family != AF_INET6 ) ) continue;
36413dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
36423dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			// <rdar://problem/6220642> iTunes 8: Bonjour doesn't work after upgrading iTunes 8
36433dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			// Seems as if the problem here is a buggy implementation of some network interface
36443dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			// driver. It is reporting that is has a link-local address when it is actually
36453dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			// disconnected. This was causing a problem in AddressToIndexAndMask.
36463dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			// The solution is to call AddressToIndexAndMask first, and if unable to lookup
36473dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			// the address, to ignore that address.
36483dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
36493dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			ipv4Index = 0;
36503dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			memset( &ipv4Netmask, 0, sizeof( ipv4Netmask ) );
36513dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
36523dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			if ( family == AF_INET )
36533dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			{
36543dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin				err = AddressToIndexAndMask( addr->Address.lpSockaddr, &ipv4Index, ( struct sockaddr* ) &ipv4Netmask );
36553dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
36563dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin				if ( err )
36573dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin				{
36583dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin					err = 0;
36593dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin					continue;
36603dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin				}
36613dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			}
36623dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
36633dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			ifa = (struct ifaddrs *) calloc( 1, sizeof( struct ifaddrs ) );
36643dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			require_action( ifa, exit, err = WSAENOBUFS );
36653dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
36663dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			*next = ifa;
36673dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			next  = &ifa->ifa_next;
36683dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
36693dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			// Get the name.
36703dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
36713dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			size = strlen( iaa->AdapterName ) + 1;
36723dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			ifa->ifa_name = (char *) malloc( size );
36733dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			require_action( ifa->ifa_name, exit, err = WSAENOBUFS );
36743dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			memcpy( ifa->ifa_name, iaa->AdapterName, size );
36753dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
36763dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			// Get interface flags.
36773dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
36783dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			ifa->ifa_flags = 0;
36793dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			if( iaa->OperStatus == IfOperStatusUp ) 		ifa->ifa_flags |= IFF_UP;
36803dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			if( iaa->IfType == IF_TYPE_SOFTWARE_LOOPBACK )	ifa->ifa_flags |= IFF_LOOPBACK;
36813dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			else if ( IsPointToPoint( addr ) )				ifa->ifa_flags |= IFF_POINTTOPOINT;
36823dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			if( !( iaa->Flags & IP_ADAPTER_NO_MULTICAST ) )	ifa->ifa_flags |= IFF_MULTICAST;
36833dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
36843dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
36853dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			// <rdar://problem/4045657> Interface index being returned is 512
36863dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			//
36873dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			// Windows does not have a uniform scheme for IPv4 and IPv6 interface indexes.
36883dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			// This code used to shift the IPv4 index up to ensure uniqueness between
36893dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			// it and IPv6 indexes.  Although this worked, it was somewhat confusing to developers, who
36903dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			// then see interface indexes passed back that don't correspond to anything
36913dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			// that is seen in Win32 APIs or command line tools like "route".  As a relatively
36923dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			// small percentage of developers are actively using IPv6, it seems to
36933dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			// make sense to make our use of IPv4 as confusion free as possible.
36943dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			// So now, IPv6 interface indexes will be shifted up by a
36953dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			// constant value which will serve to uniquely identify them, and we will
36963dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			// leave IPv4 interface indexes unmodified.
36973dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
36983dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			switch( family )
36993dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			{
37003dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin				case AF_INET:  ifa->ifa_extra.index = iaa->IfIndex; break;
37013dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin				case AF_INET6: ifa->ifa_extra.index = ipv6IfIndex + kIPv6IfIndexBase;	 break;
37023dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin				default: break;
37033dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			}
37043dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
37053dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			// Get lease lifetime
37063dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
37073dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			if ( ( iaa->IfType != IF_TYPE_SOFTWARE_LOOPBACK ) && ( addr->LeaseLifetime != 0 ) && ( addr->ValidLifetime != 0xFFFFFFFF ) )
37083dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			{
37093dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin				ifa->ifa_dhcpEnabled		= TRUE;
37103dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin				ifa->ifa_dhcpLeaseExpires	= time( NULL ) + addr->ValidLifetime;
37113dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			}
37123dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			else
37133dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			{
37143dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin				ifa->ifa_dhcpEnabled		= FALSE;
37153dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin				ifa->ifa_dhcpLeaseExpires	= 0;
37163dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			}
37173dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
37183dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			if ( iaa->PhysicalAddressLength == sizeof( ifa->ifa_physaddr ) )
37193dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			{
37203dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin				memcpy( ifa->ifa_physaddr, iaa->PhysicalAddress, iaa->PhysicalAddressLength );
37213dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			}
37223dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
37233dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			// Because we don't get notified of womp changes, we're going to just assume
37243dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			// that all wired interfaces have it enabled. Before we go to sleep, we'll check
37253dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			// if the interface actually supports it, and update mDNS->SystemWakeOnLANEnabled
37263dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			// accordingly
37273dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
37283dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			ifa->ifa_womp = ( iaa->IfType == IF_TYPE_ETHERNET_CSMACD ) ? mDNStrue : mDNSfalse;
37293dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
37303dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			// Get address.
37313dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
37323dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			switch( family )
37333dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			{
37343dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin				case AF_INET:
37353dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin				case AF_INET6:
37363dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin					ifa->ifa_addr = (struct sockaddr *) calloc( 1, (size_t) addr->Address.iSockaddrLength );
37373dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin					require_action( ifa->ifa_addr, exit, err = WSAENOBUFS );
37383dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin					memcpy( ifa->ifa_addr, addr->Address.lpSockaddr, (size_t) addr->Address.iSockaddrLength );
37393dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin					break;
37403dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
37413dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin				default:
37423dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin					break;
37433dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			}
37443dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			check( ifa->ifa_addr );
37453dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
37463dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			// Get subnet mask (IPv4)/link prefix (IPv6). It is specified as a bit length (e.g. 24 for 255.255.255.0).
37473dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
37483dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			prefixLength = 0;
37493dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			for( prefixIndex = 0, prefix = firstPrefix; prefix; ++prefixIndex, prefix = prefix->Next )
37503dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			{
37513dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin				if( ( prefix->Address.lpSockaddr->sa_family == family ) && ( prefixIndex == addrIndex ) )
37523dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin				{
37533dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin					check_string( prefix->Address.lpSockaddr->sa_family == family, "addr family != netmask family" );
37543dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin					prefixLength = prefix->PrefixLength;
37553dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin					break;
37563dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin				}
37573dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			}
37583dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			switch( family )
37593dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			{
37603dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin				case AF_INET:
37613dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin				{
37623dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin					struct sockaddr_in * sa4;
37633dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
37643dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin					sa4 = (struct sockaddr_in *) calloc( 1, sizeof( *sa4 ) );
37653dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin					require_action( sa4, exit, err = WSAENOBUFS );
37663dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin					sa4->sin_family = AF_INET;
37673dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin					sa4->sin_addr.s_addr = ipv4Netmask.sin_addr.s_addr;
37683dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
37693dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin					dlog( kDebugLevelInfo, DEBUG_NAME "%s: IPv4 mask = %s\n", __ROUTINE__, inet_ntoa( sa4->sin_addr ) );
37703dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin					ifa->ifa_netmask = (struct sockaddr *) sa4;
37713dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin					break;
37723dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin				}
37733dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
37743dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin				case AF_INET6:
37753dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin				{
37763dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin					struct sockaddr_in6 *		sa6;
37773dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin					int							len;
37783dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin					int							maskIndex;
37793dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin					uint8_t						maskByte;
37803dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
37813dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin					require_action( prefixLength <= 128, exit, err = ERROR_INVALID_DATA );
37823dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
37833dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin					sa6 = (struct sockaddr_in6 *) calloc( 1, sizeof( *sa6 ) );
37843dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin					require_action( sa6, exit, err = WSAENOBUFS );
37853dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin					sa6->sin6_family = AF_INET6;
37863dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
37873dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin					if( prefixLength == 0 )
37883dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin					{
37893dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin						dlog( kDebugLevelWarning, DEBUG_NAME "%s: IPv6 link prefix 0, defaulting to /128\n", __ROUTINE__ );
37903dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin						prefixLength = 128;
37913dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin					}
37923dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin					maskIndex = 0;
37933dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin					for( len = (int) prefixLength; len > 0; len -= 8 )
37943dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin					{
37953dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin						if( len >= 8 ) maskByte = 0xFF;
37963dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin						else		   maskByte = (uint8_t)( ( 0xFFU << ( 8 - len ) ) & 0xFFU );
37973dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin						sa6->sin6_addr.s6_addr[ maskIndex++ ] = maskByte;
37983dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin					}
37993dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin					ifa->ifa_netmask = (struct sockaddr *) sa6;
38003dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin					break;
38013dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin				}
38023dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
38033dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin				default:
38043dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin					break;
38053dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			}
38063dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		}
38073dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	}
38083dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
38093dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	// Success!
38103dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
38113dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	if( outAddrs )
38123dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	{
38133dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		*outAddrs = head;
38143dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		head = NULL;
38153dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	}
38163dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	err = ERROR_SUCCESS;
38173dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
38183dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlinexit:
38193dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	if( head )
38203dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	{
38213dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		freeifaddrs( head );
38223dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	}
38233dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	if( iaaList )
38243dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	{
38253dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		free( iaaList );
38263dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	}
38273dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	return( (int) err );
38283dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin}
38293dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
38303dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin#endif	// MDNS_WINDOWS_USE_IPV6_IF_ADDRS
38313dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
38323dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//===========================================================================================================================
38333dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//	getifaddrs_ipv4
38343dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//===========================================================================================================================
38353dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
38363dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinmDNSlocal int	getifaddrs_ipv4( struct ifaddrs **outAddrs )
38373dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin{
38383dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	int						err;
38393dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	SOCKET					sock;
38403dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	DWORD					size;
38413dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	DWORD					actualSize;
38423dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	INTERFACE_INFO *		buffer;
38433dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	INTERFACE_INFO *		tempBuffer;
38443dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	INTERFACE_INFO *		ifInfo;
38453dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	int						n;
38463dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	int						i;
38473dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	struct ifaddrs *		head;
38483dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	struct ifaddrs **		next;
38493dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	struct ifaddrs *		ifa;
38503dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
38513dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	sock	= INVALID_SOCKET;
38523dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	buffer	= NULL;
38533dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	head	= NULL;
38543dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	next	= &head;
38553dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
38563dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	// Get the interface list. WSAIoctl is called with SIO_GET_INTERFACE_LIST, but since this does not provide a
38573dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	// way to determine the size of the interface list beforehand, we have to start with an initial size guess and
38583dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	// call WSAIoctl repeatedly with increasing buffer sizes until it succeeds. Limit this to 100 tries for safety.
38593dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
38603dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	sock = socket( AF_INET, SOCK_DGRAM, IPPROTO_UDP );
38613dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	err = translate_errno( IsValidSocket( sock ), errno_compat(), kUnknownErr );
38623dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	require_noerr( err, exit );
38633dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
38643dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	n = 0;
38653dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	size = 16 * sizeof( INTERFACE_INFO );
38663dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	for( ;; )
38673dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	{
38683dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		tempBuffer = (INTERFACE_INFO *) realloc( buffer, size );
38693dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		require_action( tempBuffer, exit, err = WSAENOBUFS );
38703dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		buffer = tempBuffer;
38713dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
38723dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		err = WSAIoctl( sock, SIO_GET_INTERFACE_LIST, NULL, 0, buffer, size, &actualSize, NULL, NULL );
38733dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		if( err == 0 )
38743dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		{
38753dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			break;
38763dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		}
38773dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
38783dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		++n;
38793dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		require_action( n < 100, exit, err = WSAEADDRNOTAVAIL );
38803dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
38813dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		size += ( 16 * sizeof( INTERFACE_INFO ) );
38823dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	}
38833dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	check( actualSize <= size );
38843dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	check( ( actualSize % sizeof( INTERFACE_INFO ) ) == 0 );
38853dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	n = (int)( actualSize / sizeof( INTERFACE_INFO ) );
38863dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
38873dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	// Process the raw interface list and build a linked list of IPv4 interfaces.
38883dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
38893dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	for( i = 0; i < n; ++i )
38903dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	{
38913dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		uint32_t ifIndex;
38923dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		struct sockaddr_in netmask;
38933dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
38943dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		ifInfo = &buffer[ i ];
38953dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		if( ifInfo->iiAddress.Address.sa_family != AF_INET )
38963dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		{
38973dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			continue;
38983dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		}
38993dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
39003dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		// <rdar://problem/6220642> iTunes 8: Bonjour doesn't work after upgrading iTunes 8
39013dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		// See comment in getifaddrs_ipv6
39023dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
39033dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		ifIndex = 0;
39043dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		memset( &netmask, 0, sizeof( netmask ) );
39053dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		err = AddressToIndexAndMask( ( struct sockaddr* ) &ifInfo->iiAddress.AddressIn, &ifIndex, ( struct sockaddr* ) &netmask );
39063dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
39073dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		if ( err )
39083dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		{
39093dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			continue;
39103dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		}
39113dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
39123dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		ifa = (struct ifaddrs *) calloc( 1, sizeof( struct ifaddrs ) );
39133dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		require_action( ifa, exit, err = WSAENOBUFS );
39143dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
39153dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		*next = ifa;
39163dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		next  = &ifa->ifa_next;
39173dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
39183dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		// Get the name.
39193dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
39203dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		ifa->ifa_name = (char *) malloc( 16 );
39213dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		require_action( ifa->ifa_name, exit, err = WSAENOBUFS );
39223dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		sprintf( ifa->ifa_name, "%d", i + 1 );
39233dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
39243dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		// Get interface flags.
39253dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
39263dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		ifa->ifa_flags = (u_int) ifInfo->iiFlags;
39273dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
39283dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		// Get addresses.
39293dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
39303dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		if ( ifInfo->iiAddress.Address.sa_family == AF_INET )
39313dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		{
39323dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			struct sockaddr_in *		sa4;
39333dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
39343dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			sa4 = &ifInfo->iiAddress.AddressIn;
39353dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			ifa->ifa_addr = (struct sockaddr *) calloc( 1, sizeof( *sa4 ) );
39363dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			require_action( ifa->ifa_addr, exit, err = WSAENOBUFS );
39373dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			memcpy( ifa->ifa_addr, sa4, sizeof( *sa4 ) );
39383dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
39393dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			ifa->ifa_netmask = (struct sockaddr*) calloc(1, sizeof( *sa4 ) );
39403dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			require_action( ifa->ifa_netmask, exit, err = WSAENOBUFS );
39413dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
39423dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			// <rdar://problem/4076478> Service won't start on Win2K. The address
39433dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			// family field was not being initialized.
39443dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
39453dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			ifa->ifa_netmask->sa_family = AF_INET;
39463dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			( ( struct sockaddr_in* ) ifa->ifa_netmask )->sin_addr = netmask.sin_addr;
39473dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			ifa->ifa_extra.index = ifIndex;
39483dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		}
39493dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		else
39503dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		{
39513dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			// Emulate an interface index.
39523dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
39533dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			ifa->ifa_extra.index = (uint32_t)( i + 1 );
39543dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		}
39553dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	}
39563dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
39573dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	// Success!
39583dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
39593dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	if( outAddrs )
39603dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	{
39613dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		*outAddrs = head;
39623dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		head = NULL;
39633dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	}
39643dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	err = 0;
39653dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
39663dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlinexit:
39673dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
39683dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	if( head )
39693dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	{
39703dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		freeifaddrs( head );
39713dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	}
39723dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	if( buffer )
39733dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	{
39743dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		free( buffer );
39753dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	}
39763dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	if( sock != INVALID_SOCKET )
39773dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	{
39783dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		closesocket( sock );
39793dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	}
39803dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	return( err );
39813dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin}
39823dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
39833dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//===========================================================================================================================
39843dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//	freeifaddrs
39853dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//===========================================================================================================================
39863dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
39873dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinmDNSlocal void	freeifaddrs( struct ifaddrs *inIFAs )
39883dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin{
39893dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	struct ifaddrs *		p;
39903dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	struct ifaddrs *		q;
39913dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
39923dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	// Free each piece of the structure. Set to null after freeing to handle macro-aliased fields.
39933dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
39943dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	for( p = inIFAs; p; p = q )
39953dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	{
39963dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		q = p->ifa_next;
39973dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
39983dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		if( p->ifa_name )
39993dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		{
40003dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			free( p->ifa_name );
40013dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			p->ifa_name = NULL;
40023dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		}
40033dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		if( p->ifa_addr )
40043dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		{
40053dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			free( p->ifa_addr );
40063dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			p->ifa_addr = NULL;
40073dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		}
40083dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		if( p->ifa_netmask )
40093dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		{
40103dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			free( p->ifa_netmask );
40113dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			p->ifa_netmask = NULL;
40123dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		}
40133dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		if( p->ifa_broadaddr )
40143dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		{
40153dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			free( p->ifa_broadaddr );
40163dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			p->ifa_broadaddr = NULL;
40173dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		}
40183dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		if( p->ifa_dstaddr )
40193dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		{
40203dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			free( p->ifa_dstaddr );
40213dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			p->ifa_dstaddr = NULL;
40223dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		}
40233dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		if( p->ifa_data )
40243dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		{
40253dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			free( p->ifa_data );
40263dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			p->ifa_data = NULL;
40273dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		}
40283dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		free( p );
40293dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	}
40303dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin}
40313dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
40323dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
40333dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//===========================================================================================================================
40343dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//	GetPrimaryInterface
40353dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//===========================================================================================================================
40363dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
40373dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinmDNSlocal DWORD
40383dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinGetPrimaryInterface()
40393dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin{
40403dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	PMIB_IPFORWARDTABLE	pIpForwardTable	= NULL;
40413dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	DWORD				dwSize			= 0;
40423dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	BOOL				bOrder			= FALSE;
40433dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	OSStatus			err;
40443dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	DWORD				index			= 0;
40453dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	DWORD				metric			= 0;
40463dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	unsigned long int	i;
40473dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
40483dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	// Find out how big our buffer needs to be.
40493dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
40503dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	err = GetIpForwardTable(NULL, &dwSize, bOrder);
40513dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	require_action( err == ERROR_INSUFFICIENT_BUFFER, exit, err = kUnknownErr );
40523dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
40533dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	// Allocate the memory for the table
40543dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
40553dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	pIpForwardTable = (PMIB_IPFORWARDTABLE) malloc( dwSize );
40563dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	require_action( pIpForwardTable, exit, err = kNoMemoryErr );
40573dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
40583dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	// Now get the table.
40593dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
40603dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	err = GetIpForwardTable(pIpForwardTable, &dwSize, bOrder);
40613dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	require_noerr( err, exit );
40623dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
40633dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
40643dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	// Search for the row in the table we want.
40653dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
40663dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	for ( i = 0; i < pIpForwardTable->dwNumEntries; i++)
40673dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	{
40683dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		// Look for a default route
40693dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
40703dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		if ( pIpForwardTable->table[i].dwForwardDest == 0 )
40713dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		{
40723dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			if ( index && ( pIpForwardTable->table[i].dwForwardMetric1 >= metric ) )
40733dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			{
40743dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin				continue;
40753dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			}
40763dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
40773dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			index	= pIpForwardTable->table[i].dwForwardIfIndex;
40783dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			metric	= pIpForwardTable->table[i].dwForwardMetric1;
40793dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		}
40803dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	}
40813dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
40823dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlinexit:
40833dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
40843dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	if ( pIpForwardTable != NULL )
40853dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	{
40863dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		free( pIpForwardTable );
40873dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	}
40883dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
40893dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	return index;
40903dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin}
40913dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
40923dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
40933dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//===========================================================================================================================
40943dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//	AddressToIndexAndMask
40953dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//===========================================================================================================================
40963dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
40973dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinmDNSlocal mStatus
40983dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinAddressToIndexAndMask( struct sockaddr * addr, uint32_t * ifIndex, struct sockaddr * mask  )
40993dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin{
41003dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	// Before calling AddIPAddress we use GetIpAddrTable to get
41013dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	// an adapter to which we can add the IP.
41023dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
41033dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	PMIB_IPADDRTABLE	pIPAddrTable	= NULL;
41043dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	DWORD				dwSize			= 0;
41053dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	mStatus				err				= mStatus_UnknownErr;
41063dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	DWORD				i;
41073dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
41083dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	// For now, this is only for IPv4 addresses.  That is why we can safely cast
41093dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	// addr's to sockaddr_in.
41103dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
41113dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	require_action( addr->sa_family == AF_INET, exit, err = mStatus_UnknownErr );
41123dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
41133dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	// Make an initial call to GetIpAddrTable to get the
41143dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	// necessary size into the dwSize variable
41153dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
41163dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	for ( i = 0; i < 100; i++ )
41173dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	{
41183dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		err = GetIpAddrTable( pIPAddrTable, &dwSize, 0 );
41193dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
41203dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		if ( err != ERROR_INSUFFICIENT_BUFFER )
41213dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		{
41223dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			break;
41233dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		}
41243dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
41253dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		pIPAddrTable = (MIB_IPADDRTABLE *) realloc( pIPAddrTable, dwSize );
41263dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		require_action( pIPAddrTable, exit, err = WSAENOBUFS );
41273dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	}
41283dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
41293dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	require_noerr( err, exit );
41303dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	err = mStatus_UnknownErr;
41313dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
41323dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	for ( i = 0; i < pIPAddrTable->dwNumEntries; i++ )
41333dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	{
41343dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		if ( ( ( struct sockaddr_in* ) addr )->sin_addr.s_addr == pIPAddrTable->table[i].dwAddr )
41353dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		{
41363dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			*ifIndex											= pIPAddrTable->table[i].dwIndex;
41373dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			( ( struct sockaddr_in*) mask )->sin_addr.s_addr	= pIPAddrTable->table[i].dwMask;
41383dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			err													= mStatus_NoError;
41393dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			break;
41403dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		}
41413dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	}
41423dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
41433dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlinexit:
41443dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
41453dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	if ( pIPAddrTable )
41463dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	{
41473dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		free( pIPAddrTable );
41483dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	}
41493dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
41503dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	return err;
41513dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin}
41523dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
41533dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
41543dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//===========================================================================================================================
41553dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//	CanReceiveUnicast
41563dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//===========================================================================================================================
41573dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
41583dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinmDNSlocal mDNSBool	CanReceiveUnicast( void )
41593dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin{
41603dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	mDNSBool				ok;
41613dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	SocketRef				sock;
41623dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	struct sockaddr_in		addr;
41633dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
41643dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	// Try to bind to the port without the SO_REUSEADDR option to test if someone else has already bound to it.
41653dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
41663dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	sock = socket( AF_INET, SOCK_DGRAM, IPPROTO_UDP );
41673dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	check_translated_errno( IsValidSocket( sock ), errno_compat(), kUnknownErr );
41683dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	ok = IsValidSocket( sock );
41693dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	if( ok )
41703dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	{
41713dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		mDNSPlatformMemZero( &addr, sizeof( addr ) );
41723dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		addr.sin_family			= AF_INET;
41733dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		addr.sin_port			= MulticastDNSPort.NotAnInteger;
41743dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		addr.sin_addr.s_addr	= htonl( INADDR_ANY );
41753dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
41763dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		ok = ( bind( sock, (struct sockaddr *) &addr, sizeof( addr ) ) == 0 );
41773dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		close_compat( sock );
41783dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	}
41793dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
41803dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	dlog( kDebugLevelInfo, DEBUG_NAME "Unicast UDP responses %s\n", ok ? "okay" : "*not allowed*" );
41813dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	return( ok );
41823dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin}
41833dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
41843dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
41853dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//===========================================================================================================================
41863dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//	IsPointToPoint
41873dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//===========================================================================================================================
41883dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
41893dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinmDNSlocal mDNSBool IsPointToPoint( IP_ADAPTER_UNICAST_ADDRESS * addr )
41903dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin{
41913dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	struct ifaddrs	*	addrs	=	NULL;
41923dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	struct ifaddrs	*	p		=	NULL;
41933dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	OSStatus			err;
41943dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	mDNSBool			ret		=	mDNSfalse;
41953dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
41963dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	// For now, only works for IPv4 interfaces
41973dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
41983dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	if ( addr->Address.lpSockaddr->sa_family == AF_INET )
41993dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	{
42003dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		// The getifaddrs_ipv4 call will give us correct information regarding IFF_POINTTOPOINT flags.
42013dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
42023dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		err = getifaddrs_ipv4( &addrs );
42033dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		require_noerr( err, exit );
42043dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
42053dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		for ( p = addrs; p; p = p->ifa_next )
42063dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		{
42073dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			if ( ( addr->Address.lpSockaddr->sa_family == p->ifa_addr->sa_family ) &&
42083dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			     ( ( ( struct sockaddr_in* ) addr->Address.lpSockaddr )->sin_addr.s_addr == ( ( struct sockaddr_in* ) p->ifa_addr )->sin_addr.s_addr ) )
42093dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			{
42103dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin				ret = ( p->ifa_flags & IFF_POINTTOPOINT ) ? mDNStrue : mDNSfalse;
42113dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin				break;
42123dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			}
42133dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		}
42143dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	}
42153dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
42163dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlinexit:
42173dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
42183dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	if ( addrs )
42193dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	{
42203dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		freeifaddrs( addrs );
42213dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	}
42223dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
42233dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	return ret;
42243dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin}
42253dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
42263dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
42273dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//===========================================================================================================================
42283dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//	GetWindowsVersionString
42293dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//===========================================================================================================================
42303dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
42313dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinmDNSlocal OSStatus	GetWindowsVersionString( char *inBuffer, size_t inBufferSize )
42323dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin{
42333dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin#if( !defined( VER_PLATFORM_WIN32_CE ) )
42343dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	#define VER_PLATFORM_WIN32_CE		3
42353dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin#endif
42363dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
42373dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	OSStatus				err;
42383dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	OSVERSIONINFO			osInfo;
42393dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	BOOL					ok;
42403dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	const char *			versionString;
42413dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	DWORD					platformID;
42423dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	DWORD					majorVersion;
42433dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	DWORD					minorVersion;
42443dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	DWORD					buildNumber;
42453dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
42463dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	versionString = "unknown Windows version";
42473dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
42483dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	osInfo.dwOSVersionInfoSize = sizeof( OSVERSIONINFO );
42493dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	ok = GetVersionEx( &osInfo );
42503dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	err = translate_errno( ok, (OSStatus) GetLastError(), kUnknownErr );
42513dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	require_noerr( err, exit );
42523dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
42533dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	platformID		= osInfo.dwPlatformId;
42543dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	majorVersion	= osInfo.dwMajorVersion;
42553dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	minorVersion	= osInfo.dwMinorVersion;
42563dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	buildNumber		= osInfo.dwBuildNumber & 0xFFFF;
42573dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
42583dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	if( ( platformID == VER_PLATFORM_WIN32_WINDOWS ) && ( majorVersion == 4 ) )
42593dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	{
42603dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		if( ( minorVersion < 10 ) && ( buildNumber == 950 ) )
42613dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		{
42623dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			versionString	= "Windows 95";
42633dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		}
42643dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		else if( ( minorVersion < 10 ) && ( ( buildNumber > 950 ) && ( buildNumber <= 1080 ) ) )
42653dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		{
42663dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			versionString	= "Windows 95 SP1";
42673dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		}
42683dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		else if( ( minorVersion < 10 ) && ( buildNumber > 1080 ) )
42693dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		{
42703dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			versionString	= "Windows 95 OSR2";
42713dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		}
42723dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		else if( ( minorVersion == 10 ) && ( buildNumber == 1998 ) )
42733dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		{
42743dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			versionString	= "Windows 98";
42753dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		}
42763dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		else if( ( minorVersion == 10 ) && ( ( buildNumber > 1998 ) && ( buildNumber < 2183 ) ) )
42773dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		{
42783dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			versionString	= "Windows 98 SP1";
42793dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		}
42803dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		else if( ( minorVersion == 10 ) && ( buildNumber >= 2183 ) )
42813dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		{
42823dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			versionString	= "Windows 98 SE";
42833dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		}
42843dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		else if( minorVersion == 90 )
42853dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		{
42863dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			versionString	= "Windows ME";
42873dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		}
42883dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	}
42893dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	else if( platformID == VER_PLATFORM_WIN32_NT )
42903dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	{
42913dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		if( ( majorVersion == 3 ) && ( minorVersion == 51 ) )
42923dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		{
42933dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			versionString	= "Windows NT 3.51";
42943dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		}
42953dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		else if( ( majorVersion == 4 ) && ( minorVersion == 0 ) )
42963dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		{
42973dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			versionString	= "Windows NT 4";
42983dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		}
42993dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		else if( ( majorVersion == 5 ) && ( minorVersion == 0 ) )
43003dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		{
43013dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			versionString	= "Windows 2000";
43023dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		}
43033dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		else if( ( majorVersion == 5 ) && ( minorVersion == 1 ) )
43043dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		{
43053dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			versionString	= "Windows XP";
43063dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		}
43073dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		else if( ( majorVersion == 5 ) && ( minorVersion == 2 ) )
43083dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		{
43093dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			versionString	= "Windows Server 2003";
43103dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		}
43113dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	}
43123dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	else if( platformID == VER_PLATFORM_WIN32_CE )
43133dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	{
43143dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		versionString		= "Windows CE";
43153dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	}
43163dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
43173dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlinexit:
43183dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	if( inBuffer && ( inBufferSize > 0 ) )
43193dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	{
43203dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		inBufferSize -= 1;
43213dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		strncpy( inBuffer, versionString, inBufferSize );
43223dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		inBuffer[ inBufferSize ] = '\0';
43233dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	}
43243dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	return( err );
43253dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin}
43263dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
43273dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
43283dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//===========================================================================================================================
43293dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//	RegQueryString
43303dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//===========================================================================================================================
43313dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
43323dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinmDNSlocal mStatus
43333dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinRegQueryString( HKEY key, LPCSTR valueName, LPSTR * string, DWORD * stringLen, DWORD * enabled )
43343dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin{
43353dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	DWORD	type;
43363dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	int		i;
43373dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	mStatus err;
43383dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
43393dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	*stringLen	= MAX_ESCAPED_DOMAIN_NAME;
43403dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	*string		= NULL;
43413dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	i			= 0;
43423dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
43433dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	do
43443dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	{
43453dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		if ( *string )
43463dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		{
43473dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			free( *string );
43483dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		}
43493dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
43503dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		*string = (char*) malloc( *stringLen );
43513dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		require_action( *string, exit, err = mStatus_NoMemoryErr );
43523dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
43533dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		err = RegQueryValueExA( key, valueName, 0, &type, (LPBYTE) *string, stringLen );
43543dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
43553dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		i++;
43563dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	}
43573dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	while ( ( err == ERROR_MORE_DATA ) && ( i < 100 ) );
43583dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
43593dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	require_noerr_quiet( err, exit );
43603dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
43613dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	if ( enabled )
43623dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	{
43633dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		DWORD dwSize = sizeof( DWORD );
43643dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
43653dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		err = RegQueryValueEx( key, TEXT("Enabled"), NULL, NULL, (LPBYTE) enabled, &dwSize );
43663dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		check_noerr( err );
43673dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
43683dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		err = kNoErr;
43693dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	}
43703dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
43713dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlinexit:
43723dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
43733dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	return err;
43743dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin}
43753dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
43763dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
43773dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//===========================================================================================================================
43783dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//	StringToAddress
43793dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//===========================================================================================================================
43803dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
43813dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinmDNSlocal mStatus StringToAddress( mDNSAddr * ip, LPSTR string )
43823dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin{
43833dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	struct sockaddr_in6 sa6;
43843dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	struct sockaddr_in	sa4;
43853dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	INT					dwSize;
43863dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	mStatus				err;
43873dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
43883dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	sa6.sin6_family	= AF_INET6;
43893dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	dwSize			= sizeof( sa6 );
43903dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
43913dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	err = WSAStringToAddressA( string, AF_INET6, NULL, (struct sockaddr*) &sa6, &dwSize );
43923dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
43933dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	if ( err == mStatus_NoError )
43943dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	{
43953dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		err = SetupAddr( ip, (struct sockaddr*) &sa6 );
43963dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		require_noerr( err, exit );
43973dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	}
43983dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	else
43993dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	{
44003dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		sa4.sin_family = AF_INET;
44013dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		dwSize = sizeof( sa4 );
44023dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
44033dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		err = WSAStringToAddressA( string, AF_INET, NULL, (struct sockaddr*) &sa4, &dwSize );
44043dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		err = translate_errno( err == 0, WSAGetLastError(), kUnknownErr );
44053dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		require_noerr( err, exit );
44063dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
44073dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		err = SetupAddr( ip, (struct sockaddr*) &sa4 );
44083dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		require_noerr( err, exit );
44093dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	}
44103dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
44113dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlinexit:
44123dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
44133dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	return err;
44143dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin}
44153dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
44163dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
44173dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//===========================================================================================================================
44183dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//	myGetIfAddrs
44193dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//===========================================================================================================================
44203dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
44213dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinmDNSlocal struct ifaddrs*
44223dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinmyGetIfAddrs(int refresh)
44233dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin{
44243dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	static struct ifaddrs *ifa = NULL;
44253dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
44263dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	if (refresh && ifa)
44273dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	{
44283dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		freeifaddrs(ifa);
44293dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		ifa = NULL;
44303dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	}
44313dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
44323dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	if (ifa == NULL)
44333dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	{
44343dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		getifaddrs(&ifa);
44353dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	}
44363dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
44373dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	return ifa;
44383dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin}
44393dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
44403dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
44413dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//===========================================================================================================================
44423dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//	TCHARtoUTF8
44433dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//===========================================================================================================================
44443dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
44453dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinmDNSlocal OSStatus
44463dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinTCHARtoUTF8( const TCHAR *inString, char *inBuffer, size_t inBufferSize )
44473dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin{
44483dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin#if( defined( UNICODE ) || defined( _UNICODE ) )
44493dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	OSStatus		err;
44503dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	int				len;
44513dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
44523dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	len = WideCharToMultiByte( CP_UTF8, 0, inString, -1, inBuffer, (int) inBufferSize, NULL, NULL );
44533dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	err = translate_errno( len > 0, errno_compat(), kUnknownErr );
44543dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	require_noerr( err, exit );
44553dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
44563dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlinexit:
44573dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	return( err );
44583dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin#else
44593dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	return( WindowsLatin1toUTF8( inString, inBuffer, inBufferSize ) );
44603dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin#endif
44613dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin}
44623dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
44633dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
44643dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//===========================================================================================================================
44653dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//	WindowsLatin1toUTF8
44663dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//===========================================================================================================================
44673dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
44683dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinmDNSlocal OSStatus
44693dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinWindowsLatin1toUTF8( const char *inString, char *inBuffer, size_t inBufferSize )
44703dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin{
44713dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	OSStatus		err;
44723dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	WCHAR *			utf16;
44733dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	int				len;
44743dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
44753dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	utf16 = NULL;
44763dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
44773dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	// Windows doesn't support going directly from Latin-1 to UTF-8 so we have to go from Latin-1 to UTF-16 first.
44783dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
44793dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	len = MultiByteToWideChar( CP_ACP, 0, inString, -1, NULL, 0 );
44803dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	err = translate_errno( len > 0, errno_compat(), kUnknownErr );
44813dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	require_noerr( err, exit );
44823dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
44833dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	utf16 = (WCHAR *) malloc( len * sizeof( *utf16 ) );
44843dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	require_action( utf16, exit, err = kNoMemoryErr );
44853dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
44863dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	len = MultiByteToWideChar( CP_ACP, 0, inString, -1, utf16, len );
44873dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	err = translate_errno( len > 0, errno_compat(), kUnknownErr );
44883dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	require_noerr( err, exit );
44893dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
44903dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	// Now convert the temporary UTF-16 to UTF-8.
44913dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
44923dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	len = WideCharToMultiByte( CP_UTF8, 0, utf16, -1, inBuffer, (int) inBufferSize, NULL, NULL );
44933dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	err = translate_errno( len > 0, errno_compat(), kUnknownErr );
44943dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	require_noerr( err, exit );
44953dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
44963dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlinexit:
44973dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	if( utf16 ) free( utf16 );
44983dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	return( err );
44993dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin}
45003dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
45013dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
45023dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//===========================================================================================================================
45033dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//	TCPCloseSocket
45043dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//===========================================================================================================================
45053dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
45063dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinmDNSlocal void
45073dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinTCPCloseSocket( TCPSocket * sock )
45083dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin{
45093dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	dlog( kDebugLevelChatty, DEBUG_NAME "closing TCPSocket 0x%x:%d\n", sock, sock->fd );
45103dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
45113dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	RemoveFromList( &gTCPDispatchableSockets, sock );
45123dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
45133dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	if ( sock->fd != INVALID_SOCKET )
45143dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	{
45153dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		closesocket( sock->fd );
45163dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		sock->fd = INVALID_SOCKET;
45173dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	}
45183dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin}
45193dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
45203dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
45213dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//===========================================================================================================================
45223dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//	TCPFreeSocket
45233dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//===========================================================================================================================
45243dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
45253dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinmDNSlocal void CALLBACK
45263dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinTCPFreeSocket( TCPSocket *sock )
45273dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin{
45283dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	check( sock );
45293dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
45303dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	dlog( kDebugLevelChatty, DEBUG_NAME "freeing TCPSocket 0x%x:%d\n", sock, sock->fd );
45313dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
45323dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	if ( sock->connectEvent )
45333dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	{
45343dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		CloseHandle( sock->connectEvent );
45353dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		sock->connectEvent = NULL;
45363dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	}
45373dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
45383dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	if ( sock->fd != INVALID_SOCKET )
45393dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	{
45403dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		closesocket( sock->fd );
45413dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		sock->fd = INVALID_SOCKET;
45423dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	}
45433dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
45443dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	free( sock );
45453dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin}
45463dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
45473dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
45483dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//===========================================================================================================================
45493dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//  UDPCloseSocket
45503dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//===========================================================================================================================
45513dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
45523dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinmDNSlocal void
45533dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinUDPCloseSocket( UDPSocket * sock )
45543dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin{
45553dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	dlog( kDebugLevelChatty, DEBUG_NAME "closing UDPSocket %d\n", sock->fd );
45563dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
45573dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	RemoveFromList( &gUDPDispatchableSockets, sock );
45583dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
45593dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	if ( sock->fd != INVALID_SOCKET )
45603dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	{
45613dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		closesocket( sock->fd );
45623dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		sock->fd = INVALID_SOCKET;
45633dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	}
45643dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin}
45653dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
45663dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
45673dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//===========================================================================================================================
45683dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//  UDPFreeSocket
45693dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//===========================================================================================================================
45703dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
45713dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinmDNSlocal void CALLBACK
45723dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinUDPFreeSocket( UDPSocket * sock )
45733dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin{
45743dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin    check( sock );
45753dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
45763dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	dlog( kDebugLevelChatty, DEBUG_NAME "freeing UDPSocket %d\n", sock->fd );
45773dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
45783dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin    if ( sock->fd != INVALID_SOCKET )
45793dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin    {
45803dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin        closesocket( sock->fd );
45813dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		sock->fd = INVALID_SOCKET;
45823dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin    }
45833dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
45843dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin    free( sock );
45853dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin}
45863dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
45873dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//===========================================================================================================================
45883dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//	SetupAddr
45893dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin//===========================================================================================================================
45903dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
45913dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinmDNSlocal mStatus SetupAddr(mDNSAddr *ip, const struct sockaddr *const sa)
45923dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	{
45933dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	if (!sa) { LogMsg("SetupAddr ERROR: NULL sockaddr"); return(mStatus_Invalid); }
45943dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
45953dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	if (sa->sa_family == AF_INET)
45963dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		{
45973dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		struct sockaddr_in *ifa_addr = (struct sockaddr_in *)sa;
45983dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		ip->type = mDNSAddrType_IPv4;
45993dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		ip->ip.v4.NotAnInteger = ifa_addr->sin_addr.s_addr;
46003dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		return(mStatus_NoError);
46013dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		}
46023dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
46033dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	if (sa->sa_family == AF_INET6)
46043dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		{
46053dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		struct sockaddr_in6 *ifa_addr = (struct sockaddr_in6 *)sa;
46063dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		ip->type = mDNSAddrType_IPv6;
46073dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		if (IN6_IS_ADDR_LINKLOCAL(&ifa_addr->sin6_addr)) ifa_addr->sin6_addr.u.Word[1] = 0;
46083dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		ip->ip.v6 = *(mDNSv6Addr*)&ifa_addr->sin6_addr;
46093dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		return(mStatus_NoError);
46103dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		}
46113dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
46123dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	LogMsg("SetupAddr invalid sa_family %d", sa->sa_family);
46133dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	return(mStatus_Invalid);
46143dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	}
46153dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
46163dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
46173dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinmDNSlocal void GetDDNSFQDN( domainname *const fqdn )
46183dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin{
46193dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	LPSTR		name = NULL;
46203dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	DWORD		dwSize;
46213dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	DWORD		enabled;
46223dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	HKEY		key = NULL;
46233dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	OSStatus	err;
46243dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
46253dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	check( fqdn );
46263dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
46273dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	// Initialize
46283dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
46293dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	fqdn->c[0] = '\0';
46303dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
46313dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	// Get info from Bonjour registry key
46323dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
46333dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	err = RegCreateKey( HKEY_LOCAL_MACHINE, kServiceParametersNode TEXT("\\DynDNS\\Setup\\") kServiceDynDNSHostNames, &key );
46343dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	require_noerr( err, exit );
46353dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
46363dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	err = RegQueryString( key, "", &name, &dwSize, &enabled );
46373dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	if ( !err && ( name[0] != '\0' ) && enabled )
46383dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	{
46393dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		if ( !MakeDomainNameFromDNSNameString( fqdn, name ) || !fqdn->c[0] )
46403dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		{
46413dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			dlog( kDebugLevelError, "bad DDNS host name in registry: %s", name[0] ? name : "(unknown)");
46423dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		}
46433dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	}
46443dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
46453dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlinexit:
46463dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
46473dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	if ( key )
46483dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	{
46493dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		RegCloseKey( key );
46503dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		key = NULL;
46513dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	}
46523dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
46533dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	if ( name )
46543dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	{
46553dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		free( name );
46563dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		name = NULL;
46573dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	}
46583dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin}
46593dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
46603dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
46613dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin#ifdef UNICODE
46623dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinmDNSlocal void GetDDNSDomains( DNameListElem ** domains, LPCWSTR lpSubKey )
46633dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin#else
46643dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinmDNSlocal void GetDDNSConfig( DNameListElem ** domains, LPCSTR lpSubKey )
46653dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin#endif
46663dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin{
46673dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	char		subKeyName[kRegistryMaxKeyLength + 1];
46683dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	DWORD		cSubKeys = 0;
46693dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	DWORD		cbMaxSubKey;
46703dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	DWORD		cchMaxClass;
46713dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	DWORD		dwSize;
46723dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	HKEY		key = NULL;
46733dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	HKEY		subKey = NULL;
46743dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	domainname	dname;
46753dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	DWORD		i;
46763dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	OSStatus	err;
46773dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
46783dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	check( domains );
46793dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
46803dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	// Initialize
46813dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
46823dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	*domains = NULL;
46833dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
46843dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	err = RegCreateKey( HKEY_LOCAL_MACHINE, lpSubKey, &key );
46853dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	require_noerr( err, exit );
46863dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
46873dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	// Get information about this node
46883dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
46893dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	err = RegQueryInfoKey( key, NULL, NULL, NULL, &cSubKeys, &cbMaxSubKey, &cchMaxClass, NULL, NULL, NULL, NULL, NULL );
46903dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	require_noerr( err, exit );
46913dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
46923dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	for ( i = 0; i < cSubKeys; i++)
46933dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	{
46943dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		DWORD enabled;
46953dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
46963dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		dwSize = kRegistryMaxKeyLength;
46973dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
46983dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		err = RegEnumKeyExA( key, i, subKeyName, &dwSize, NULL, NULL, NULL, NULL );
46993dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
47003dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		if ( !err )
47013dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		{
47023dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			err = RegOpenKeyExA( key, subKeyName, 0, KEY_READ, &subKey );
47033dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			require_noerr( err, exit );
47043dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
47053dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			dwSize = sizeof( DWORD );
47063dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			err = RegQueryValueExA( subKey, "Enabled", NULL, NULL, (LPBYTE) &enabled, &dwSize );
47073dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
47083dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			if ( !err && ( subKeyName[0] != '\0' ) && enabled )
47093dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			{
47103dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin				if ( !MakeDomainNameFromDNSNameString( &dname, subKeyName ) || !dname.c[0] )
47113dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin				{
47123dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin					dlog( kDebugLevelError, "bad DDNS domain in registry: %s", subKeyName[0] ? subKeyName : "(unknown)");
47133dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin				}
47143dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin				else
47153dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin				{
47163dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin					DNameListElem * domain = (DNameListElem*) malloc( sizeof( DNameListElem ) );
47173dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin					require_action( domain, exit, err = mStatus_NoMemoryErr );
47183dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
47193dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin					AssignDomainName(&domain->name, &dname);
47203dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin					domain->next = *domains;
47213dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
47223dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin					*domains = domain;
47233dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin				}
47243dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			}
47253dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
47263dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			RegCloseKey( subKey );
47273dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			subKey = NULL;
47283dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		}
47293dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	}
47303dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
47313dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlinexit:
47323dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
47333dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	if ( subKey )
47343dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	{
47353dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		RegCloseKey( subKey );
47363dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	}
47373dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
47383dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	if ( key )
47393dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	{
47403dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		RegCloseKey( key );
47413dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	}
47423dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin}
47433dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
47443dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
47453dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinmDNSlocal void SetDomainSecret( mDNS * const m, const domainname * inDomain )
47463dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin{
47473dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	char					domainUTF8[ 256 ];
47483dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	DomainAuthInfo			*foundInList;
47493dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	DomainAuthInfo			*ptr;
47503dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	char					outDomain[ 256 ];
47513dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	char					outKey[ 256 ];
47523dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	char					outSecret[ 256 ];
47533dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	OSStatus				err;
47543dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
47553dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	ConvertDomainNameToCString( inDomain, domainUTF8 );
47563dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
47573dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	// If we're able to find a secret for this domain
47583dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
47593dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	if ( LsaGetSecret( domainUTF8, outDomain, sizeof( outDomain ), outKey, sizeof( outKey ), outSecret, sizeof( outSecret ) ) )
47603dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	{
47613dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		domainname domain;
47623dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		domainname key;
47633dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
47643dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		// Tell the core about this secret
47653dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
47663dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		MakeDomainNameFromDNSNameString( &domain, outDomain );
47673dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		MakeDomainNameFromDNSNameString( &key, outKey );
47683dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
47693dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		for (foundInList = m->AuthInfoList; foundInList; foundInList = foundInList->next)
47703dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			if (SameDomainName(&foundInList->domain, &domain ) ) break;
47713dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
47723dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		ptr = foundInList;
47733dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
47743dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		if (!ptr)
47753dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		{
47763dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			ptr = (DomainAuthInfo*)malloc(sizeof(DomainAuthInfo));
47773dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			require_action( ptr, exit, err = mStatus_NoMemoryErr );
47783dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		}
47793dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
47803dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		err = mDNS_SetSecretForDomain(m, ptr, &domain, &key, outSecret, NULL, 0, NULL );
47813dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		require_action( err != mStatus_BadParamErr, exit, if (!foundInList ) mDNSPlatformMemFree( ptr ) );
47823dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
47833dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		debugf("Setting shared secret for zone %s with key %##s", outDomain, key.c);
47843dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	}
47853dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
47863dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlinexit:
47873dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
47883dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	return;
47893dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin}
47903dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
47913dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
47923dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinmDNSlocal VOID CALLBACK
47933dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinCheckFileSharesProc( LPVOID arg, DWORD dwTimerLowValue, DWORD dwTimerHighValue )
47943dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin{
47953dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	mDNS * const m = ( mDNS * const ) arg;
47963dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
47973dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	( void ) dwTimerLowValue;
47983dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	( void ) dwTimerHighValue;
47993dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
48003dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	CheckFileShares( m );
48013dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin}
48023dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
48033dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
48043dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinmDNSlocal unsigned __stdcall
48053dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinSMBRegistrationThread( void * arg )
48063dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin{
48073dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	mDNS * const m = ( mDNS * const ) arg;
48083dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	DNSServiceRef sref = NULL;
48093dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	HANDLE		handles[ 3 ];
48103dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	mDNSu8		txtBuf[ 256 ];
48113dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	mDNSu8	*	txtPtr;
48123dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	size_t		keyLen;
48133dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	size_t		valLen;
48143dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	mDNSIPPort	port = { { SMBPortAsNumber >> 8, SMBPortAsNumber & 0xFF } };
48153dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	DNSServiceErrorType err;
48163dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
48173dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	DEBUG_UNUSED( arg );
48183dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
48193dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	handles[ 0 ] = gSMBThreadStopEvent;
48203dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	handles[ 1 ] = gSMBThreadRegisterEvent;
48213dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	handles[ 2 ] = gSMBThreadDeregisterEvent;
48223dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
48233dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	memset( txtBuf, 0, sizeof( txtBuf )  );
48243dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	txtPtr = txtBuf;
48253dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	keyLen = strlen( "netbios=" );
48263dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	valLen = strlen( m->p->nbname );
48273dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	require_action( valLen < 32, exit, err = kUnknownErr );	// This should never happen, but check to avoid further memory corruption
48283dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	*txtPtr++ = ( mDNSu8 ) ( keyLen + valLen );
48293dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	memcpy( txtPtr, "netbios=", keyLen );
48303dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	txtPtr += keyLen;
48313dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	if ( valLen ) { memcpy( txtPtr, m->p->nbname, valLen ); txtPtr += ( mDNSu8 ) valLen; }
48323dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	keyLen = strlen( "domain=" );
48333dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	valLen = strlen( m->p->nbdomain );
48343dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	require_action( valLen < 32, exit, err = kUnknownErr );	// This should never happen, but check to avoid further memory corruption
48353dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	*txtPtr++ = ( mDNSu8 )( keyLen + valLen );
48363dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	memcpy( txtPtr, "domain=", keyLen );
48373dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	txtPtr += keyLen;
48383dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	if ( valLen ) { memcpy( txtPtr, m->p->nbdomain, valLen ); txtPtr += valLen; }
48393dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
48403dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	for ( ;; )
48413dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	{
48423dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		DWORD ret;
48433dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
48443dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		ret = WaitForMultipleObjects( 3, handles, FALSE, INFINITE );
48453dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
48463dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		if ( ret != WAIT_FAILED )
48473dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		{
48483dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			if ( ret == kSMBStopEvent )
48493dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			{
48503dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin				break;
48513dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			}
48523dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			else if ( ret == kSMBRegisterEvent )
48533dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			{
48543dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin				err = gDNSServiceRegister( &sref, 0, 0, NULL, "_smb._tcp,_file", NULL, NULL, ( uint16_t ) port.NotAnInteger, ( mDNSu16 )( txtPtr - txtBuf ), txtBuf, NULL, NULL );
48553dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
48563dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin				if ( err )
48573dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin				{
48583dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin					LogMsg( "SMBRegistrationThread: DNSServiceRegister returned %d\n", err );
48593dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin					sref = NULL;
48603dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin					break;
48613dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin				}
48623dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			}
48633dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			else if ( ret == kSMBDeregisterEvent )
48643dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			{
48653dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin				if ( sref )
48663dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin				{
48673dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin					gDNSServiceRefDeallocate( sref );
48683dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin					sref = NULL;
48693dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin				}
48703dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			}
48713dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		}
48723dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		else
48733dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		{
48743dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			LogMsg( "SMBRegistrationThread:  WaitForMultipleObjects returned %d\n", GetLastError() );
48753dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			break;
48763dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		}
48773dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	}
48783dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
48793dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlinexit:
48803dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
48813dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	if ( sref != NULL )
48823dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	{
48833dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		gDNSServiceRefDeallocate( sref );
48843dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		sref = NULL;
48853dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	}
48863dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
48873dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	SetEvent( gSMBThreadQuitEvent );
48883dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	_endthreadex( 0 );
48893dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	return 0;
48903dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin}
48913dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
48923dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
48933dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinmDNSlocal void
48943dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinCheckFileShares( mDNS * const m )
48953dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin{
48963dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	PSHARE_INFO_1	bufPtr = ( PSHARE_INFO_1 ) NULL;
48973dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	DWORD			entriesRead = 0;
48983dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	DWORD			totalEntries = 0;
48993dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	DWORD			resume = 0;
49003dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	mDNSBool		advertise = mDNSfalse;
49013dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	mDNSBool		fileSharing = mDNSfalse;
49023dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	mDNSBool		printSharing = mDNSfalse;
49033dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	HKEY			key = NULL;
49043dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	BOOL			retry = FALSE;
49053dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	NET_API_STATUS  res;
49063dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	mStatus			err;
49073dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
49083dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	check( m );
49093dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
49103dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	// Only do this if we're not shutting down
49113dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
49123dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	require_action_quiet( m->AdvertiseLocalAddresses && !m->ShutdownTime, exit, err = kNoErr );
49133dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
49143dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	err = RegCreateKey( HKEY_LOCAL_MACHINE, kServiceParametersNode L"\\Services\\SMB", &key );
49153dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
49163dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	if ( !err )
49173dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	{
49183dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		DWORD dwSize = sizeof( DWORD );
49193dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		RegQueryValueEx( key, L"Advertise", NULL, NULL, (LPBYTE) &advertise, &dwSize );
49203dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	}
49213dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
49223dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	if ( advertise && mDNSIsFileAndPrintSharingEnabled( &retry ) )
49233dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	{
49243dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		dlog( kDebugLevelTrace, DEBUG_NAME "Sharing is enabled\n" );
49253dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
49263dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		res = NetShareEnum( NULL, 1, ( LPBYTE* )&bufPtr, MAX_PREFERRED_LENGTH, &entriesRead, &totalEntries, &resume );
49273dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
49283dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		if ( ( res == ERROR_SUCCESS ) || ( res == ERROR_MORE_DATA ) )
49293dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		{
49303dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			PSHARE_INFO_1 p = bufPtr;
49313dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			DWORD i;
49323dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
49333dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			for( i = 0; i < entriesRead; i++ )
49343dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			{
49353dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin				// We are only interested if the user is sharing anything other
49363dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin				// than the built-in "print$" source
49373dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
49383dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin				if ( ( p->shi1_type == STYPE_DISKTREE ) && ( wcscmp( p->shi1_netname, TEXT( "print$" ) ) != 0 ) )
49393dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin				{
49403dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin					fileSharing = mDNStrue;
49413dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin				}
49423dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin				else if ( p->shi1_type == STYPE_PRINTQ )
49433dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin				{
49443dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin					printSharing = mDNStrue;
49453dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin				}
49463dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
49473dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin				p++;
49483dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			}
49493dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
49503dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			NetApiBufferFree( bufPtr );
49513dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			bufPtr = NULL;
49523dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			retry = FALSE;
49533dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		}
49543dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		else if ( res == NERR_ServerNotStarted )
49553dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		{
49563dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			retry = TRUE;
49573dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		}
49583dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	}
49593dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
49603dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	if ( retry )
49613dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	{
49623dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		__int64			qwTimeout;
49633dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		LARGE_INTEGER   liTimeout;
49643dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
49653dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		qwTimeout = -m->p->checkFileSharesTimeout * 10000000;
49663dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		liTimeout.LowPart  = ( DWORD )( qwTimeout & 0xFFFFFFFF );
49673dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		liTimeout.HighPart = ( LONG )( qwTimeout >> 32 );
49683dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
49693dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		SetWaitableTimer( m->p->checkFileSharesTimer, &liTimeout, 0, CheckFileSharesProc, m, FALSE );
49703dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	}
49713dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
49723dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	if ( !m->p->smbFileSharing && fileSharing )
49733dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	{
49743dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		if ( !gSMBThread )
49753dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		{
49763dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			if ( !gDNSSDLibrary )
49773dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			{
49783dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin				gDNSSDLibrary = LoadLibrary( TEXT( "dnssd.dll" ) );
49793dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin				require_action( gDNSSDLibrary, exit, err = GetLastError() );
49803dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			}
49813dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
49823dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			if ( !gDNSServiceRegister )
49833dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			{
49843dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin				gDNSServiceRegister = ( DNSServiceRegisterFunc ) GetProcAddress( gDNSSDLibrary, "DNSServiceRegister" );
49853dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin				require_action( gDNSServiceRegister, exit, err = GetLastError() );
49863dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			}
49873dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
49883dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			if ( !gDNSServiceRefDeallocate )
49893dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			{
49903dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin				gDNSServiceRefDeallocate = ( DNSServiceRefDeallocateFunc ) GetProcAddress( gDNSSDLibrary, "DNSServiceRefDeallocate" );
49913dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin				require_action( gDNSServiceRefDeallocate, exit, err = GetLastError() );
49923dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			}
49933dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
49943dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			if ( !gSMBThreadRegisterEvent )
49953dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			{
49963dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin				gSMBThreadRegisterEvent = CreateEvent( NULL, FALSE, FALSE, NULL );
49973dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin				require_action( gSMBThreadRegisterEvent != NULL, exit, err = GetLastError() );
49983dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			}
49993dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
50003dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			if ( !gSMBThreadDeregisterEvent )
50013dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			{
50023dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin				gSMBThreadDeregisterEvent = CreateEvent( NULL, FALSE, FALSE, NULL );
50033dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin				require_action( gSMBThreadDeregisterEvent != NULL, exit, err = GetLastError() );
50043dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			}
50053dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
50063dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			if ( !gSMBThreadStopEvent )
50073dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			{
50083dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin				gSMBThreadStopEvent = CreateEvent( NULL, FALSE, FALSE, NULL );
50093dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin				require_action( gSMBThreadStopEvent != NULL, exit, err = GetLastError() );
50103dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			}
50113dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
50123dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			if ( !gSMBThreadQuitEvent )
50133dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			{
50143dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin				gSMBThreadQuitEvent = CreateEvent( NULL, FALSE, FALSE, NULL );
50153dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin				require_action( gSMBThreadQuitEvent != NULL, exit, err = GetLastError() );
50163dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			}
50173dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
50183dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			gSMBThread = ( HANDLE ) _beginthreadex( NULL, 0, SMBRegistrationThread, m, 0, NULL );
50193dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			require_action( gSMBThread != NULL, exit, err = GetLastError() );
50203dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		}
50213dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
50223dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		SetEvent( gSMBThreadRegisterEvent );
50233dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
50243dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		m->p->smbFileSharing = mDNStrue;
50253dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	}
50263dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	else if ( m->p->smbFileSharing && !fileSharing )
50273dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	{
50283dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		dlog( kDebugLevelTrace, DEBUG_NAME "deregistering smb type\n" );
50293dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
50303dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		if ( gSMBThreadDeregisterEvent != NULL )
50313dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		{
50323dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			SetEvent( gSMBThreadDeregisterEvent );
50333dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		}
50343dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
50353dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		m->p->smbFileSharing = mDNSfalse;
50363dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	}
50373dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
50383dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlinexit:
50393dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
50403dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	if ( key )
50413dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	{
50423dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		RegCloseKey( key );
50433dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	}
50443dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin}
50453dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
50463dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
50473dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinBOOL
50483dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinIsWOMPEnabled( mDNS * const m )
50493dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin{
50503dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	BOOL enabled;
50513dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
50523dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	mDNSInterfaceData * ifd;
50533dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
50543dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	enabled = FALSE;
50553dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
50563dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	for( ifd = m->p->interfaceList; ifd; ifd = ifd->next )
50573dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	{
50583dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		if ( IsWOMPEnabledForAdapter( ifd->name ) )
50593dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		{
50603dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			enabled = TRUE;
50613dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			break;
50623dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		}
50633dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	}
50643dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
50653dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	return enabled;
50663dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin}
50673dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
50683dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
50693dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinmDNSlocal mDNSu8
50703dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinIsWOMPEnabledForAdapter( const char * adapterName )
50713dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin{
50723dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	char						fileName[80];
50733dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	NDIS_OID					oid;
50743dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin    DWORD						count;
50753dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin    HANDLE						handle	= INVALID_HANDLE_VALUE;
50763dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	NDIS_PNP_CAPABILITIES	*	pNPC	= NULL;
50773dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	int							err;
50783dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	mDNSu8						ok		= TRUE;
50793dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
50803dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	require_action( adapterName != NULL, exit, ok = FALSE );
50813dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
50823dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	dlog( kDebugLevelTrace, DEBUG_NAME "IsWOMPEnabledForAdapter: %s\n", adapterName );
50833dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
50843dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin    // Construct a device name to pass to CreateFile
50853dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
50863dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	strncpy_s( fileName, sizeof( fileName ), DEVICE_PREFIX, strlen( DEVICE_PREFIX ) );
50873dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	strcat_s( fileName, sizeof( fileName ), adapterName );
50883dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin    handle = CreateFileA( fileName, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, INVALID_HANDLE_VALUE );
50893dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	require_action ( handle != INVALID_HANDLE_VALUE, exit, ok = FALSE );
50903dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
50913dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	// We successfully opened the driver, format the IOCTL to pass the driver.
50923dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
50933dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	oid = OID_PNP_CAPABILITIES;
50943dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	pNPC = ( NDIS_PNP_CAPABILITIES * ) malloc( sizeof( NDIS_PNP_CAPABILITIES ) );
50953dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	require_action( pNPC != NULL, exit, ok = FALSE );
50963dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	ok = ( mDNSu8 ) DeviceIoControl( handle, IOCTL_NDIS_QUERY_GLOBAL_STATS, &oid, sizeof( oid ), pNPC, sizeof( NDIS_PNP_CAPABILITIES ), &count, NULL );
50973dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	err = translate_errno( ok, GetLastError(), kUnknownErr );
50983dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	require_action( !err, exit, ok = FALSE );
50993dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	ok = ( mDNSu8 ) ( ( count == sizeof( NDIS_PNP_CAPABILITIES ) ) && ( pNPC->Flags & NDIS_DEVICE_WAKE_ON_MAGIC_PACKET_ENABLE ) );
51003dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
51013dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlinexit:
51023dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
51033dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	if ( pNPC != NULL )
51043dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	{
51053dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		free( pNPC );
51063dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	}
51073dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
51083dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin    if ( handle != INVALID_HANDLE_VALUE )
51093dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin    {
51103dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		CloseHandle( handle );
51113dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin    }
51123dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
51133dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	dlog( kDebugLevelTrace, DEBUG_NAME "IsWOMPEnabledForAdapter returns %s\n", ok ? "true" : "false" );
51143dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
51153dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	return ( mDNSu8 ) ok;
51163dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin}
51173dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
51183dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
51193dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlinvoid
51203dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinDispatchSocketEvents( mDNS * const inMDNS )
51213dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin{
51223dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	UDPSocket * udpSock;
51233dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	TCPSocket * tcpSock;
51243dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
51253dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	while ( ( udpSock = ( UDPSocket* ) gUDPDispatchableSockets.Head ) != NULL )
51263dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	{
51273dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		dlog( kDebugLevelChatty, DEBUG_NAME "%s: calling DispatchUDPEvent on socket %d, error = %d, bytesTransferred = %d\n",
51283dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		                                     __ROUTINE__, udpSock->fd, udpSock->overlapped.error, udpSock->overlapped.bytesTransferred );
51293dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		RemoveFromList( &gUDPDispatchableSockets, udpSock );
51303dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		DispatchUDPEvent( inMDNS, udpSock );
51313dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	}
51323dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
51333dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	while ( ( tcpSock = ( TCPSocket* ) gTCPDispatchableSockets.Head ) != NULL )
51343dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	{
51353dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		dlog( kDebugLevelChatty, DEBUG_NAME "%s: calling DispatchTCPEvent on socket %d, error = %d, bytesTransferred = %d\n",
51363dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		                                     __ROUTINE__, tcpSock->fd, tcpSock->overlapped.error, tcpSock->overlapped.bytesTransferred );
51373dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		RemoveFromList( &gTCPDispatchableSockets, tcpSock );
51383dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		DispatchTCPEvent( inMDNS, tcpSock );
51393dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	}
51403dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin}
51413dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
51423dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
51433dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinmDNSlocal void
51443dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinDispatchUDPEvent( mDNS * const inMDNS, UDPSocket * sock )
51453dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin{
51463dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	( void ) inMDNS;
51473dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
51483dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	// If we've closed the socket, then we want to ignore
51493dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	// this read.  The packet might have been queued before
51503dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	// the socket was closed.
51513dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
51523dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	if ( sock->fd != INVALID_SOCKET )
51533dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	{
51543dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		const mDNSInterfaceID	iid = sock->ifd ? sock->ifd->interfaceInfo.InterfaceID : NULL;
51553dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		mDNSu8				*	end = ( (mDNSu8 *) &sock->packet ) + sock->overlapped.bytesTransferred;
51563dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
51573dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		dlog( kDebugLevelChatty, DEBUG_NAME "calling mDNSCoreReceive on socket: %d\n", sock->fd );
51583dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		mDNSCoreReceive( sock->m, &sock->packet, end, &sock->overlapped.srcAddr, sock->overlapped.srcPort, &sock->overlapped.dstAddr, sock->overlapped.dstPort, iid );
51593dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	}
51603dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
51613dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	// If the socket is still good, then start up another asynchronous read
51623dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
51633dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	if ( sock->fd != INVALID_SOCKET )
51643dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	{
51653dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		int err = UDPBeginRecv( sock );
51663dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		check_noerr( err );
51673dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	}
51683dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin}
51693dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
51703dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
51713dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinmDNSlocal void
51723dfdc952a3e125868a0a4123e40e1f7fd868af21Casey DahlinDispatchTCPEvent( mDNS * const inMDNS, TCPSocket * sock )
51733dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin{
51743dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	( void ) inMDNS;
51753dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
51763dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	if ( sock->fd != INVALID_SOCKET )
51773dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	{
51783dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		sock->eptr += sock->overlapped.bytesTransferred;
51793dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		sock->lastError = sock->overlapped.error;
51803dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
51813dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		if ( !sock->overlapped.error && !sock->overlapped.bytesTransferred )
51823dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		{
51833dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			sock->closed = TRUE;
51843dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		}
51853dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
51863dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		if ( sock->readEventHandler != NULL )
51873dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		{
51883dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			dlog( kDebugLevelChatty, DEBUG_NAME "calling TCP read handler  on socket: %d\n", sock->fd );
51893dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin			sock->readEventHandler( sock );
51903dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		}
51913dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	}
51923dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
51933dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	// If the socket is still good, then start up another asynchronous read
51943dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin
51953dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	if ( !sock->closed && ( sock->fd != INVALID_SOCKET ) )
51963dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	{
51973dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		int err = TCPBeginRecv( sock );
51983dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin		check_noerr( err );
51993dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin	}
52003dfdc952a3e125868a0a4123e40e1f7fd868af21Casey Dahlin}
5201