/* -*- Mode: C; tab-width: 4 -*-
 *
 * Copyright (c) 2004 Apple Computer, Inc. All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *     http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifdef _LEGACY_NAT_TRAVERSAL_

#include "stdlib.h"			// For strtol()
#include "string.h"			// For strlcpy(), For strncpy(), strncasecmp()

#if defined( WIN32 )
#	include <winsock2.h>
#	include <ws2tcpip.h>
#	define strcasecmp	_stricmp
#	define strncasecmp	_strnicmp
#	define mDNSASLLog( UUID, SUBDOMAIN, RESULT, SIGNATURE, FORMAT, ... ) ;

static int
inet_pton( int family, const char * addr, void * dst )
	{
	struct sockaddr_storage ss;
	int sslen = sizeof( ss );

	ZeroMemory( &ss, sizeof( ss ) );
	ss.ss_family = (ADDRESS_FAMILY)family;

	if ( WSAStringToAddressA( (LPSTR)addr, family, NULL, ( struct sockaddr* ) &ss, &sslen ) == 0 )
		{
		if ( family == AF_INET ) { memcpy( dst, &( ( struct sockaddr_in* ) &ss)->sin_addr, sizeof( IN_ADDR ) ); return 1; }
		else if ( family == AF_INET6 ) { memcpy( dst, &( ( struct sockaddr_in6* ) &ss)->sin6_addr, sizeof( IN6_ADDR ) ); return 1; }
		else return 0;
		}
	else return 0;
	}
#else
#	include <arpa/inet.h>		// For inet_pton()
#endif

#include "mDNSEmbeddedAPI.h"
#include "uDNS.h"			// For natTraversalHandleAddressReply() etc.

// used to format SOAP port mapping arguments
typedef struct Property_struct
	{
	char *name;
	char *type;
	char *value;
	} Property;

// All of the text parsing in this file is intentionally transparent so that we know exactly
// what's being done to the text, with an eye towards preventing security problems.

// This is an evolving list of useful acronyms to know. Please add to it at will.
// ST      Service Type
// NT      Notification Type
// USN     Unique Service Name
// UDN     Unique Device Name
// UUID    Universally Unique Identifier
// URN/urn Universal Resource Name

// Forward declaration because of circular reference:
// SendPortMapRequest -> SendSOAPMsgControlAction -> MakeTCPConnection -> tcpConnectionCallback -> handleLNTPortMappingResponse
// In the event of a port conflict, handleLNTPortMappingResponse then increments tcpInfo->retries and calls back to SendPortMapRequest to try again
mDNSlocal mStatus SendPortMapRequest(mDNS *m, NATTraversalInfo *n);

#define RequestedPortNum(n) (mDNSVal16(mDNSIPPortIsZero((n)->RequestedPort) ? (n)->IntPort : (n)->RequestedPort) + (mDNSu16)(n)->tcpInfo.retries)

// Note that this function assumes src is already NULL terminated
mDNSlocal void AllocAndCopy(mDNSu8 **const dst, const mDNSu8 *const src)
	{
	if (src == mDNSNULL) return;
	if ((*dst = mDNSPlatformMemAllocate((mDNSu32)strlen((char*)src) + 1)) == mDNSNULL)
		{ LogMsg("AllocAndCopy: can't allocate string"); return; }
	strcpy((char*)*dst, (char*)src);
	}

// This function does a simple parse of an HTTP URL that may include a hostname, port, and path
// If found in the URL, addressAndPort and path out params will point to newly allocated space (and will leak if they were previously pointing at allocated space)
mDNSlocal mStatus ParseHttpUrl(const mDNSu8 *ptr, const mDNSu8 *const end, mDNSu8 **const addressAndPort, mDNSIPPort *const port, mDNSu8 **const path)
	{
	// if the data begins with "http://", we assume there is a hostname and possibly a port number
	if (end - ptr >= 7 && strncasecmp((char*)ptr, "http://", 7) == 0)
		{
		int i;
		const mDNSu8 *stop = end;
		const mDNSu8 *addrPtr = mDNSNULL;
		
		ptr += 7; //skip over "http://"
		if (ptr >= end) { LogInfo("ParseHttpUrl: past end of buffer parsing host:port"); return mStatus_BadParamErr; }
		
		// find the end of the host:port
		addrPtr = ptr;
		for (i = 0; addrPtr && addrPtr != end; i++, addrPtr++) if (*addrPtr == '/') break;

		// allocate the buffer (len i+1 so we have space to terminate the string)
		if ((*addressAndPort = mDNSPlatformMemAllocate(i+1)) == mDNSNULL)
			{ LogMsg("ParseHttpUrl: can't allocate address string"); return mStatus_NoMemoryErr; }
		strncpy((char*)*addressAndPort, (char*)ptr, i);
		(*addressAndPort)[i] = '\0';

		// find the port number in the string, by looking backwards for the ':'
		stop = ptr;    // can't go back farther than the original start
		ptr = addrPtr; // move ptr to the path part
		
		for (addrPtr--; addrPtr>stop; addrPtr--)
			{
			if (*addrPtr == ':')
				{
				addrPtr++; // skip over ':'
				*port = mDNSOpaque16fromIntVal((mDNSu16)strtol((char*)addrPtr, mDNSNULL, 10)); // store it properly converted
				break;
				}
			}
		}
		
	// ptr should now point to the first character we haven't yet processed
	// everything that remains is the path
	if (path && ptr < end)
		{
		if ((*path = mDNSPlatformMemAllocate((mDNSu32)(end - ptr) + 1)) == mDNSNULL)
			{ LogMsg("ParseHttpUrl: can't mDNSPlatformMemAllocate path"); return mStatus_NoMemoryErr; }
		strncpy((char*)*path, (char*)ptr, end - ptr);
		(*path)[end - ptr] = '\0';
		}
		
	return mStatus_NoError;
	}

enum
	{
	HTTPCode_NeedMoreData = -1, // No code found in stream
	HTTPCode_Other        = -2, // Valid code other than those below found in stream
	HTTPCode_Bad          = -3,
	HTTPCode_200          = 200,
	HTTPCode_404          = 404,
	HTTPCode_500          = 500,
	};
	
mDNSlocal mDNSs16 ParseHTTPResponseCode(const mDNSu8 **const data, const mDNSu8 *const end)
	{
	const mDNSu8 *ptr = *data;
	const mDNSu8 *code;
	
	if (end - ptr < 5) return HTTPCode_NeedMoreData;
	if (strncasecmp((char*)ptr, "HTTP/", 5) != 0) return HTTPCode_Bad;
	ptr += 5;
	// should we care about the HTTP protocol version?
	
	// look for first space, which must come before first LF
	while (ptr && ptr != end)
		{
		if (*ptr == '\n') return HTTPCode_Bad;
		if (*ptr == ' ') break;
		ptr++;
		}
	if (ptr == end) return HTTPCode_NeedMoreData;
	ptr++;
	
	if (end - ptr < 3) return HTTPCode_NeedMoreData;

	code = ptr;
	ptr += 3;
	while (ptr && ptr != end)
		{
		if (*ptr == '\n') break;
		ptr++;
		}
	if (ptr == end) return HTTPCode_NeedMoreData;
	*data = ++ptr;
	
	if (memcmp((char*)code, "200", 3) == 0) return HTTPCode_200;
	if (memcmp((char*)code, "404", 3) == 0) return HTTPCode_404;
	if (memcmp((char*)code, "500", 3) == 0) return HTTPCode_500;
	
	LogInfo("ParseHTTPResponseCode found unexpected result code: %c%c%c", code[0], code[1], code[2]);
	return HTTPCode_Other;
	}

// This function parses the xml body of the device description response from the router. Basically, we look to
// make sure this is a response referencing a service we care about (WANIPConnection or WANPPPConnection),
// look for the "controlURL" header immediately following, and copy the addressing and URL info we need
mDNSlocal void handleLNTDeviceDescriptionResponse(tcpLNTInfo *tcpInfo)
	{
	mDNS    *m    = tcpInfo->m;
	const mDNSu8 *ptr  = tcpInfo->Reply;
	const mDNSu8 *end  = tcpInfo->Reply + tcpInfo->nread;
	const mDNSu8 *stop;
	mDNSs16 http_result;
	
	if (!mDNSIPPortIsZero(m->UPnPSOAPPort)) return; // already have the info we need

	http_result = ParseHTTPResponseCode(&ptr, end); // Note: modifies ptr
	if (http_result == HTTPCode_404) LNT_ClearState(m);
	if (http_result != HTTPCode_200) 
		{
		mDNSASLLog((uuid_t *)&m->asl_uuid, "natt.legacy.DeviceDescription", "noop", "HTTP Result", "HTTP code: %d", http_result);
		return;
		}

	// Always reset our flag to use WANIPConnection.  We'll use WANPPPConnection if we find it and don't find WANIPConnection.
	m->UPnPWANPPPConnection = mDNSfalse;

	// find either service we care about
	while (ptr && ptr < end)
		{
		if ((*ptr & 0xDF) == 'W' && (strncasecmp((char*)ptr, "WANIPConnection:1", 17) == 0)) break;
		ptr++;
		}
	if (ptr == end)
		{
		ptr = tcpInfo->Reply;
		while (ptr && ptr < end)
			{
			if ((*ptr & 0xDF) == 'W' && (strncasecmp((char*)ptr, "WANPPPConnection:1", 18) == 0))
				{
				m->UPnPWANPPPConnection = mDNStrue;
				break;
				}
			ptr++;
			}
		}
	if (ptr == mDNSNULL || ptr == end) { LogInfo("handleLNTDeviceDescriptionResponse: didn't find WANIPConnection:1 or WANPPPConnection:1 string"); return; }

	// find "controlURL", starting from where we left off
	while (ptr && ptr < end)
		{
		if ((*ptr & 0xDF) == 'C' && (strncasecmp((char*)ptr, "controlURL", 10) == 0)) break;			// find the first 'c'; is this controlURL? if not, keep looking
		ptr++;
		}
	if (ptr == mDNSNULL || ptr == end) { LogInfo("handleLNTDeviceDescriptionResponse: didn't find controlURL string"); return; }
	ptr += 11;							// skip over "controlURL>"
	if (ptr >= end) { LogInfo("handleLNTDeviceDescriptionResponse: past end of buffer and no body!"); return; } // check ptr again in case we skipped over the end of the buffer

	// find the end of the controlURL element
	for (stop = ptr; stop < end; stop++) { if (*stop == '<') { end = stop; break; } }

	// fill in default port
	m->UPnPSOAPPort = m->UPnPRouterPort;

	// free string pointers and set to NULL	
	if (m->UPnPSOAPAddressString != mDNSNULL)
		{
		mDNSPlatformMemFree(m->UPnPSOAPAddressString);
		m->UPnPSOAPAddressString = mDNSNULL;
		}
	if (m->UPnPSOAPURL != mDNSNULL)
		{
		mDNSPlatformMemFree(m->UPnPSOAPURL);
		m->UPnPSOAPURL = mDNSNULL; 
		}
	
	if (ParseHttpUrl(ptr, end, &m->UPnPSOAPAddressString, &m->UPnPSOAPPort, &m->UPnPSOAPURL) != mStatus_NoError) return;
	// the SOAPURL should look something like "/uuid:0013-108c-4b3f0000f3dc"

	if (m->UPnPSOAPAddressString == mDNSNULL)
		{
		ptr = tcpInfo->Reply;
		while (ptr && ptr < end)
			{
			if ((*ptr & 0xDF) == 'U' && (strncasecmp((char*)ptr, "URLBase", 7) == 0))		break;
			ptr++;
			}

		if (ptr < end)		// found URLBase
			{
			LogInfo("handleLNTDeviceDescriptionResponse: found URLBase");			
			ptr += 8; // skip over "URLBase>"
			// find the end of the URLBase element
			for (stop = ptr; stop < end; stop++) { if (*stop == '<') { end = stop; break; } }
			if (ParseHttpUrl(ptr, end, &m->UPnPSOAPAddressString, &m->UPnPSOAPPort, mDNSNULL) != mStatus_NoError)
				{
				LogInfo("handleLNTDeviceDescriptionResponse: failed to parse URLBase");
				}
			}
		
		// if all else fails, use the router address string
		if (m->UPnPSOAPAddressString == mDNSNULL) AllocAndCopy(&m->UPnPSOAPAddressString, m->UPnPRouterAddressString);
		}
	if (m->UPnPSOAPAddressString == mDNSNULL) LogMsg("handleLNTDeviceDescriptionResponse: UPnPSOAPAddressString is NULL");
	else LogInfo("handleLNTDeviceDescriptionResponse: SOAP address string [%s]", m->UPnPSOAPAddressString);

	if (m->UPnPSOAPURL == mDNSNULL) AllocAndCopy(&m->UPnPSOAPURL, m->UPnPRouterURL);
	if (m->UPnPSOAPURL == mDNSNULL) LogMsg("handleLNTDeviceDescriptionResponse: UPnPSOAPURL is NULL");
	else LogInfo("handleLNTDeviceDescriptionResponse: SOAP URL [%s]", m->UPnPSOAPURL);
	}

mDNSlocal void handleLNTGetExternalAddressResponse(tcpLNTInfo *tcpInfo)
	{
	mDNS       *m = tcpInfo->m;
	mDNSu16     err = NATErr_None;
	mDNSv4Addr  ExtAddr;
	const mDNSu8 *ptr = tcpInfo->Reply;
	const mDNSu8 *end = tcpInfo->Reply + tcpInfo->nread;
	mDNSu8       *addrend;
	static char tagname[20] = { 'N','e','w','E','x','t','e','r','n','a','l','I','P','A','d','d','r','e','s','s' };
	// Array NOT including a terminating nul

//	LogInfo("handleLNTGetExternalAddressResponse: %s", ptr);

	mDNSs16 http_result = ParseHTTPResponseCode(&ptr, end); // Note: modifies ptr
	if (http_result == HTTPCode_404) LNT_ClearState(m);
	if (http_result != HTTPCode_200)
		{
		mDNSASLLog((uuid_t *)&m->asl_uuid, "natt.legacy.AddressRequest", "noop", "HTTP Result", "HTTP code: %d", http_result);
		return;
		}

	while (ptr < end && strncasecmp((char*)ptr, tagname, sizeof(tagname))) ptr++;
	ptr += sizeof(tagname);						// Skip over "NewExternalIPAddress"
	while (ptr < end && *ptr != '>') ptr++;
	ptr += 1;									// Skip over ">"

	// Find the end of the address and terminate the string so inet_pton() can convert it
	// (Might be better to copy this to a local string here -- this is overwriting tcpInfo->Reply in-place
	addrend = (mDNSu8*)ptr;
	while (addrend < end && (mDNSIsDigit(*addrend) || *addrend == '.')) addrend++;
	if (addrend >= end) return;
	*addrend = 0;

	if (inet_pton(AF_INET, (char*)ptr, &ExtAddr) <= 0)
		{
		mDNSASLLog((uuid_t *)&m->asl_uuid, "natt.legacy.AddressRequest", "noop", "inet_pton", "");
		LogMsg("handleLNTGetExternalAddressResponse: Router returned bad address %s", ptr);
		err = NATErr_NetFail;
		ExtAddr = zerov4Addr;
		}
	if (!err) LogInfo("handleLNTGetExternalAddressResponse: External IP address is %.4a", &ExtAddr);

	natTraversalHandleAddressReply(m, err, ExtAddr);
	}

mDNSlocal void handleLNTPortMappingResponse(tcpLNTInfo *tcpInfo)
	{
	mDNS             *m         = tcpInfo->m;
	mDNSIPPort        extport   = zeroIPPort;
	const mDNSu8     *ptr       = tcpInfo->Reply;
	const mDNSu8     *const end = tcpInfo->Reply + tcpInfo->nread;
	NATTraversalInfo *natInfo;
	mDNSs16 http_result;

	for (natInfo = m->NATTraversals; natInfo; natInfo=natInfo->next) { if (natInfo == tcpInfo->parentNATInfo) break; }

	if (!natInfo) { LogInfo("handleLNTPortMappingResponse: can't find matching tcpInfo in NATTraversals!"); return; }

	http_result = ParseHTTPResponseCode(&ptr, end); // Note: modifies ptr
	if (http_result == HTTPCode_200)
		{
		LogInfo("handleLNTPortMappingResponse: got a valid response, sending reply to natTraversalHandlePortMapReply(internal %d external %d retries %d)",
			mDNSVal16(natInfo->IntPort), RequestedPortNum(natInfo), tcpInfo->retries);
	
		// Make sure to compute extport *before* we zero tcpInfo->retries
		extport = mDNSOpaque16fromIntVal(RequestedPortNum(natInfo));
		tcpInfo->retries = 0;
		natTraversalHandlePortMapReply(m, natInfo, m->UPnPInterfaceID, mStatus_NoError, extport, NATMAP_DEFAULT_LEASE);
		}
	else if (http_result == HTTPCode_500)
		{
		while (ptr && ptr != end)
			{
			if (((*ptr & 0xDF) == 'C' && end - ptr >= 8 && strncasecmp((char*)ptr, "Conflict", 8) == 0) ||
				(*ptr == '>' && end - ptr >= 15 && strncasecmp((char*)ptr, ">718</errorCode", 15) == 0))
				{
				if (tcpInfo->retries < 100)
					{ 
					tcpInfo->retries++; SendPortMapRequest(tcpInfo->m, natInfo); 
					mDNSASLLog((uuid_t *)&m->asl_uuid, "natt.legacy.PortMapRequest", "noop", "Conflict", "Retry %d", tcpInfo->retries);
					}
				else
					{
					LogMsg("handleLNTPortMappingResponse too many conflict retries %d %d", mDNSVal16(natInfo->IntPort), mDNSVal16(natInfo->RequestedPort));
					mDNSASLLog((uuid_t *)&m->asl_uuid, "natt.legacy.PortMapRequest", "noop", "Conflict - too many retries", "Retries: %d", tcpInfo->retries);
					natTraversalHandlePortMapReply(m, natInfo, m->UPnPInterfaceID, NATErr_Res, zeroIPPort, 0);
					}
				return;
				}
			ptr++;
			}
		}
	else if (http_result == HTTPCode_Bad) LogMsg("handleLNTPortMappingResponse got data that was not a valid HTTP response");
	else if (http_result == HTTPCode_Other) LogMsg("handleLNTPortMappingResponse got unexpected response code");
	else if (http_result == HTTPCode_404) LNT_ClearState(m);
	if (http_result != HTTPCode_200 && http_result != HTTPCode_500)
		mDNSASLLog((uuid_t *)&m->asl_uuid, "natt.legacy.PortMapRequest", "noop", "HTTP Result", "HTTP code: %d", http_result);
	}

mDNSlocal void DisposeInfoFromUnmapList(mDNS *m, tcpLNTInfo *tcpInfo)
	{
	tcpLNTInfo **ptr = &m->tcpInfoUnmapList;
	while (*ptr && *ptr != tcpInfo) ptr = &(*ptr)->next;
	if (*ptr) { *ptr = (*ptr)->next; mDNSPlatformMemFree(tcpInfo); }	// If we found it, cut it from our list and free the memory
	}

mDNSlocal void tcpConnectionCallback(TCPSocket *sock, void *context, mDNSBool ConnectionEstablished, mStatus err)
	{
	mStatus     status  = mStatus_NoError;
	tcpLNTInfo *tcpInfo = (tcpLNTInfo *)context;
	mDNSBool    closed  = mDNSfalse;
	long        n       = 0;
	long        nsent   = 0;

	if (tcpInfo == mDNSNULL) { LogInfo("tcpConnectionCallback: no tcpInfo context"); status = mStatus_Invalid; goto exit; }

	// The handlers below expect to be called with the lock held
	mDNS_Lock(tcpInfo->m);
	
	if (err) { LogInfo("tcpConnectionCallback: received error"); goto exit; }

	if (ConnectionEstablished)		// connection is established - send the message
		{
		LogInfo("tcpConnectionCallback: connection established, sending message");
		nsent = mDNSPlatformWriteTCP(sock, (char*)tcpInfo->Request, tcpInfo->requestLen);
		if (nsent != (long)tcpInfo->requestLen) { LogMsg("tcpConnectionCallback: error writing"); status = mStatus_UnknownErr; goto exit; }
		}
	else
		{
		n = mDNSPlatformReadTCP(sock, (char*)tcpInfo->Reply + tcpInfo->nread, tcpInfo->replyLen - tcpInfo->nread, &closed);
		LogInfo("tcpConnectionCallback: mDNSPlatformReadTCP read %d bytes", n);

		if      (n < 0)  { LogInfo("tcpConnectionCallback - read returned %d", n);                           status = mStatus_ConnFailed; goto exit; }
		else if (closed) { LogInfo("tcpConnectionCallback: socket closed by remote end %d", tcpInfo->nread); status = mStatus_ConnFailed; goto exit; }

		tcpInfo->nread += n;
		LogInfo("tcpConnectionCallback tcpInfo->nread %d", tcpInfo->nread);
		if (tcpInfo->nread > LNT_MAXBUFSIZE)
			{
			LogInfo("result truncated...");
			tcpInfo->nread = LNT_MAXBUFSIZE;
			}

		switch (tcpInfo->op)
			{
			case LNTDiscoveryOp:     handleLNTDeviceDescriptionResponse (tcpInfo); break;
			case LNTExternalAddrOp:  handleLNTGetExternalAddressResponse(tcpInfo); break;
			case LNTPortMapOp:       handleLNTPortMappingResponse       (tcpInfo); break;
			case LNTPortMapDeleteOp: status = mStatus_ConfigChanged;               break;
			default: LogMsg("tcpConnectionCallback: bad tcp operation! %d", tcpInfo->op); status = mStatus_Invalid; break;
			}
		}
exit:
	if (err || status)
		{
		mDNS   *m = tcpInfo->m;
		switch (tcpInfo->op)
			{
			case LNTDiscoveryOp:     if (m->UPnPSOAPAddressString == mDNSNULL)
										mDNSASLLog((uuid_t *)&m->asl_uuid, "natt.legacy.DeviceDescription", "failure", "SOAP Address", "");
									 if (m->UPnPSOAPURL == mDNSNULL)
										mDNSASLLog((uuid_t *)&m->asl_uuid, "natt.legacy.DeviceDescription", "failure", "SOAP path", "");
									 if (m->UPnPSOAPAddressString && m->UPnPSOAPURL)
										mDNSASLLog((uuid_t *)&m->asl_uuid, "natt.legacy.DeviceDescription", "success", "success", "");
									 break;
			case LNTExternalAddrOp:	 mDNSASLLog((uuid_t *)&m->asl_uuid, "natt.legacy.AddressRequest",
										mDNSIPv4AddressIsZero(m->ExternalAddress) ? "failure" : "success",
										mDNSIPv4AddressIsZero(m->ExternalAddress) ? "failure" : "success", "");
									 break;
			case LNTPortMapOp:       if (tcpInfo->parentNATInfo)	
										mDNSASLLog((uuid_t *)&m->asl_uuid, "natt.legacy.PortMapRequest", (tcpInfo->parentNATInfo->Result) ? "failure" : "success", 
											(tcpInfo->parentNATInfo->Result) ? "failure" : "success", "Result: %d", tcpInfo->parentNATInfo->Result);
									 break;
			case LNTPortMapDeleteOp: break;
			default:				 break;
			}

		mDNSPlatformTCPCloseConnection(tcpInfo->sock);
		tcpInfo->sock = mDNSNULL;
		if (tcpInfo->Request) { mDNSPlatformMemFree(tcpInfo->Request); tcpInfo->Request = mDNSNULL; }
		if (tcpInfo->Reply  ) { mDNSPlatformMemFree(tcpInfo->Reply);   tcpInfo->Reply   = mDNSNULL; }
		}

	if (tcpInfo) mDNS_Unlock(tcpInfo->m);

	if (status == mStatus_ConfigChanged) DisposeInfoFromUnmapList(tcpInfo->m, tcpInfo);
	}

mDNSlocal mStatus MakeTCPConnection(mDNS *const m, tcpLNTInfo *info, const mDNSAddr *const Addr, const mDNSIPPort Port, LNTOp_t op)
	{
	mStatus err = mStatus_NoError;
	mDNSIPPort srcport = zeroIPPort;

	if (mDNSIPv4AddressIsZero(Addr->ip.v4) || mDNSIPPortIsZero(Port))
	    { LogMsg("LNT MakeTCPConnection: bad address/port %#a:%d", Addr, mDNSVal16(Port)); return(mStatus_Invalid); }
	info->m         = m;
	info->Address   = *Addr;
	info->Port      = Port;
	info->op        = op;
	info->nread     = 0;
	info->replyLen  = LNT_MAXBUFSIZE;
	if      (info->Reply != mDNSNULL) mDNSPlatformMemZero(info->Reply, LNT_MAXBUFSIZE);   // reuse previously allocated buffer
	else if ((info->Reply = mDNSPlatformMemAllocate(LNT_MAXBUFSIZE)) == mDNSNULL) { LogInfo("can't allocate reply buffer"); return (mStatus_NoMemoryErr); }

	if (info->sock) { LogInfo("MakeTCPConnection: closing previous open connection"); mDNSPlatformTCPCloseConnection(info->sock); info->sock = mDNSNULL; }
	info->sock = mDNSPlatformTCPSocket(m, kTCPSocketFlags_Zero, &srcport);
	if (!info->sock) { LogMsg("LNT MakeTCPConnection: unable to create TCP socket"); mDNSPlatformMemFree(info->Reply); info->Reply = mDNSNULL; return(mStatus_NoMemoryErr); }
	LogInfo("MakeTCPConnection: connecting to %#a:%d", &info->Address, mDNSVal16(info->Port));
	err = mDNSPlatformTCPConnect(info->sock, Addr, Port, mDNSNULL, 0, tcpConnectionCallback, info);

	if      (err == mStatus_ConnPending) err = mStatus_NoError;
	else if (err == mStatus_ConnEstablished)
		{
		mDNS_DropLockBeforeCallback();
		tcpConnectionCallback(info->sock, info, mDNStrue, mStatus_NoError);
		mDNS_ReclaimLockAfterCallback();
		err = mStatus_NoError;
		}
	else
		{
		// Don't need to log this in customer builds -- it happens quite often during sleep, wake, configuration changes, etc.
		LogInfo("LNT MakeTCPConnection: connection failed");
		mDNSPlatformTCPCloseConnection(info->sock);	// Dispose the socket we created with mDNSPlatformTCPSocket() above
		info->sock = mDNSNULL;
		mDNSPlatformMemFree(info->Reply);
		info->Reply = mDNSNULL;
		}
	return(err);
	}

mDNSlocal unsigned int AddSOAPArguments(char *const buf, const unsigned int maxlen, const int numArgs, const Property *const a)
	{
	static const char f1[] = "<%s>%s</%s>";
	static const char f2[] = "<%s xmlns:dt=\"urn:schemas-microsoft-com:datatypes\" dt:dt=\"%s\">%s</%s>";
	int i, len = 0;
	*buf = 0;
	for (i = 0; i < numArgs; i++)
		{
		if (a[i].type) len += mDNS_snprintf(buf + len, maxlen - len, f2, a[i].name, a[i].type, a[i].value, a[i].name);
		else           len += mDNS_snprintf(buf + len, maxlen - len, f1, a[i].name,            a[i].value, a[i].name);
		}
	return(len);
	}

mDNSlocal mStatus SendSOAPMsgControlAction(mDNS *m, tcpLNTInfo *info, const char *const Action, const int numArgs, const Property *const Arguments, const LNTOp_t op)
	{
	// SOAP message header format -
	//  - control URL
	//  - action (string)
	//  - router's host/port ("host:port")
	//  - content-length
	static const char header[] =
		"POST %s HTTP/1.1\r\n"
		"Content-Type: text/xml; charset=\"utf-8\"\r\n"
		"SOAPAction: \"urn:schemas-upnp-org:service:WAN%sConnection:1#%s\"\r\n"
		"User-Agent: Mozilla/4.0 (compatible; UPnP/1.0; Windows 9x)\r\n"
		"Host: %s\r\n"
		"Content-Length: %d\r\n"
		"Connection: close\r\n"
		"Pragma: no-cache\r\n"
		"\r\n"
		"%s\r\n";

	static const char body1[] =
		"<?xml version=\"1.0\"?>\r\n"
		"<SOAP-ENV:Envelope"
		" xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\""
		" SOAP-ENV:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\">"
		"<SOAP-ENV:Body>"
		"<m:%s xmlns:m=\"urn:schemas-upnp-org:service:WAN%sConnection:1\">";

	static const char body2[] =
		"</m:%s>"
		"</SOAP-ENV:Body>"
		"</SOAP-ENV:Envelope>\r\n";

	mStatus err;
	char   *body = (char*)&m->omsg;			// Typically requires 1110-1122 bytes; m->omsg is 8952 bytes, which is plenty
	int     bodyLen;

	if (mDNSIPPortIsZero(m->UPnPSOAPPort) || m->UPnPSOAPURL == mDNSNULL || m->UPnPSOAPAddressString == mDNSNULL)	// if no SOAP URL or address exists get out here
		{ LogInfo("SendSOAPMsgControlAction: no SOAP port, URL or address string"); return mStatus_Invalid; }

	// Create body
	bodyLen  = mDNS_snprintf   (body,           sizeof(m->omsg),           body1,   Action,   m->UPnPWANPPPConnection ? "PPP" : "IP");
	bodyLen += AddSOAPArguments(body + bodyLen, sizeof(m->omsg) - bodyLen, numArgs, Arguments);
	bodyLen += mDNS_snprintf   (body + bodyLen, sizeof(m->omsg) - bodyLen, body2,   Action);

	// Create info->Request; the header needs to contain the bodyLen in the "Content-Length" field
	if (!info->Request) info->Request = mDNSPlatformMemAllocate(LNT_MAXBUFSIZE);
	if (!info->Request) { LogMsg("SendSOAPMsgControlAction: Can't allocate info->Request"); return mStatus_NoMemoryErr; }
	info->requestLen = mDNS_snprintf((char*)info->Request, LNT_MAXBUFSIZE, header, m->UPnPSOAPURL, m->UPnPWANPPPConnection ? "PPP" : "IP", Action, m->UPnPSOAPAddressString, bodyLen, body);

	err = MakeTCPConnection(m, info, &m->Router, m->UPnPSOAPPort, op);
	if (err) { mDNSPlatformMemFree(info->Request); info->Request = mDNSNULL; }
	return err;
	}

// Build port mapping request with new port (up to max) and send it
mDNSlocal mStatus SendPortMapRequest(mDNS *m, NATTraversalInfo *n)
	{
	char              externalPort[6];
	char              internalPort[6];
	char              localIPAddrString[30];
	char              publicPortString[40];
	Property          propArgs[8];
	mDNSu16           ReqPortNum = RequestedPortNum(n);
	NATTraversalInfo *n2 = m->NATTraversals;

	// Scan our m->NATTraversals list to make sure the external port we're requesting is locally unique.
	// UPnP gateways will report conflicts if different devices request the same external port, but if two
	// clients on the same device request the same external port the second one just stomps over the first.
	// One way this can happen is like this:
	// 1. Client A binds local port 80
	// 2. Client A requests external port 80 -> internal port 80
	// 3. UPnP NAT gateway refuses external port 80 (some other client already has it)
	// 4. Client A tries again, and successfully gets external port 80 -> internal port 81
	// 5. Client B on same machine tries to bind local port 80, and fails
	// 6. Client B tries again, and successfully binds local port 81
	// 7. Client B now requests external port 81 -> internal port 81
	// 8. UPnP NAT gateway allows this, stomping over Client A's existing mapping

	while (n2)
		{
		if (n2 == n || RequestedPortNum(n2) != ReqPortNum) n2=n2->next;
		else
			{
			if (n->tcpInfo.retries < 100)
				{
				n->tcpInfo.retries++;
				ReqPortNum = RequestedPortNum(n);	// Pick a new port number
				n2 = m->NATTraversals;				// And re-scan the list looking for conflicts
				}
			else
				{
				natTraversalHandlePortMapReply(m, n, m->UPnPInterfaceID, NATErr_Res, zeroIPPort, 0);
				return mStatus_NoError;
				}
			}
		}

	// create strings to use in the message
	mDNS_snprintf(externalPort,      sizeof(externalPort),      "%u",   ReqPortNum);
	mDNS_snprintf(internalPort,      sizeof(internalPort),      "%u",   mDNSVal16(n->IntPort));
	mDNS_snprintf(publicPortString,  sizeof(publicPortString),  "iC%u", ReqPortNum);
	mDNS_snprintf(localIPAddrString, sizeof(localIPAddrString), "%u.%u.%u.%u",
	    m->AdvertisedV4.ip.v4.b[0], m->AdvertisedV4.ip.v4.b[1], m->AdvertisedV4.ip.v4.b[2], m->AdvertisedV4.ip.v4.b[3]);

	// build the message
	mDNSPlatformMemZero(propArgs, sizeof(propArgs));
	propArgs[0].name  = "NewRemoteHost";
	propArgs[0].type  = "string";
	propArgs[0].value = "";
	propArgs[1].name  = "NewExternalPort";
	propArgs[1].type  = "ui2";
	propArgs[1].value = externalPort;
	propArgs[2].name  = "NewProtocol";
	propArgs[2].type  = "string";
	propArgs[2].value = (n->Protocol == NATOp_MapUDP) ? "UDP" : "TCP";
	propArgs[3].name  = "NewInternalPort";
	propArgs[3].type  = "ui2";
	propArgs[3].value = internalPort;
	propArgs[4].name  = "NewInternalClient";
	propArgs[4].type  = "string";
	propArgs[4].value = localIPAddrString;
	propArgs[5].name  = "NewEnabled";
	propArgs[5].type  = "boolean";
	propArgs[5].value = "1";
	propArgs[6].name  = "NewPortMappingDescription";
	propArgs[6].type  = "string";
	propArgs[6].value = publicPortString;
	propArgs[7].name  = "NewLeaseDuration";
	propArgs[7].type  = "ui4";
	propArgs[7].value = "0";

	LogInfo("SendPortMapRequest: internal %u external %u", mDNSVal16(n->IntPort), ReqPortNum);
	return SendSOAPMsgControlAction(m, &n->tcpInfo, "AddPortMapping", 8, propArgs, LNTPortMapOp);
	}

mDNSexport mStatus LNT_MapPort(mDNS *m, NATTraversalInfo *const n)
	{
	LogInfo("LNT_MapPort");
	if (n->tcpInfo.sock) return(mStatus_NoError);	// If we already have a connection up don't make another request for the same thing
	n->tcpInfo.parentNATInfo = n;
	n->tcpInfo.retries       = 0;
	return SendPortMapRequest(m, n);
	}

mDNSexport mStatus LNT_UnmapPort(mDNS *m, NATTraversalInfo *const n)
	{
	char        externalPort[10];
	Property    propArgs[3];
	tcpLNTInfo  *info;
	tcpLNTInfo  **infoPtr = &m->tcpInfoUnmapList;
	mStatus     err;

	// If no NAT gateway to talk to, no need to do all this work for nothing
	if (mDNSIPPortIsZero(m->UPnPSOAPPort) || !m->UPnPSOAPURL || !m->UPnPSOAPAddressString) return mStatus_NoError;

	mDNS_snprintf(externalPort, sizeof(externalPort), "%u", mDNSVal16(mDNSIPPortIsZero(n->RequestedPort) ? n->IntPort : n->RequestedPort));

	mDNSPlatformMemZero(propArgs, sizeof(propArgs));
	propArgs[0].name  = "NewRemoteHost";
	propArgs[0].type  = "string";
	propArgs[0].value = "";
	propArgs[1].name  = "NewExternalPort";
	propArgs[1].type  = "ui2";
	propArgs[1].value = externalPort;
	propArgs[2].name  = "NewProtocol";
	propArgs[2].type  = "string";
	propArgs[2].value = (n->Protocol == NATOp_MapUDP) ? "UDP" : "TCP";

	n->tcpInfo.parentNATInfo = n;

	// clean up previous port mapping requests and allocations
	if (n->tcpInfo.sock) LogInfo("LNT_UnmapPort: closing previous open connection");
	if (n->tcpInfo.sock   ) { mDNSPlatformTCPCloseConnection(n->tcpInfo.sock); n->tcpInfo.sock    = mDNSNULL; }
	if (n->tcpInfo.Request) { mDNSPlatformMemFree(n->tcpInfo.Request);         n->tcpInfo.Request = mDNSNULL; }
	if (n->tcpInfo.Reply  ) { mDNSPlatformMemFree(n->tcpInfo.Reply);           n->tcpInfo.Reply   = mDNSNULL; }
	
	// make a copy of the tcpInfo that we can clean up later (the one passed in will be destroyed by the client as soon as this returns)
	if ((info = mDNSPlatformMemAllocate(sizeof(tcpLNTInfo))) == mDNSNULL)
		{ LogInfo("LNT_UnmapPort: can't allocate tcpInfo"); return(mStatus_NoMemoryErr); }
	*info = n->tcpInfo;
	
	while (*infoPtr) infoPtr = &(*infoPtr)->next;	// find the end of the list
	*infoPtr = info;    // append

	err = SendSOAPMsgControlAction(m, info, "DeletePortMapping", 3, propArgs, LNTPortMapDeleteOp);
	if (err) DisposeInfoFromUnmapList(m, info);
	return err;
	}

mDNSexport mStatus LNT_GetExternalAddress(mDNS *m)
	{
	return SendSOAPMsgControlAction(m, &m->tcpAddrInfo, "GetExternalIPAddress", 0, mDNSNULL, LNTExternalAddrOp);
	}

mDNSlocal mStatus GetDeviceDescription(mDNS *m, tcpLNTInfo *info)
	{
	// Device description format -
	//  - device description URL
	//  - host/port
	static const char szSSDPMsgDescribeDeviceFMT[] =
		"GET %s HTTP/1.1\r\n"
		"Accept: text/xml, application/xml\r\n"
		"User-Agent: Mozilla/4.0 (compatible; UPnP/1.0; Windows NT/5.1)\r\n"
		"Host: %s\r\n"
		"Connection: close\r\n"
		"\r\n";

	if (!mDNSIPPortIsZero(m->UPnPSOAPPort)) return mStatus_NoError; // already have the info we need
	
	if (m->UPnPRouterURL == mDNSNULL || m->UPnPRouterAddressString == mDNSNULL) { LogInfo("GetDeviceDescription: no router URL or address string!"); return (mStatus_Invalid); }

	// build message
	if      (info->Request != mDNSNULL) mDNSPlatformMemZero(info->Request, LNT_MAXBUFSIZE); // reuse previously allocated buffer
	else if ((info->Request = mDNSPlatformMemAllocate(LNT_MAXBUFSIZE)) == mDNSNULL) { LogInfo("can't allocate send buffer for discovery"); return (mStatus_NoMemoryErr); }
	info->requestLen = mDNS_snprintf((char*)info->Request, LNT_MAXBUFSIZE, szSSDPMsgDescribeDeviceFMT, m->UPnPRouterURL, m->UPnPRouterAddressString);
	LogInfo("Describe Device: [%s]", info->Request);
	return MakeTCPConnection(m, info, &m->Router, m->UPnPRouterPort, LNTDiscoveryOp);
	}

// This function parses the response to our SSDP discovery message. Basically, we look to make sure this is a response
// referencing a service we care about (WANIPConnection or WANPPPConnection), then look for the "Location:" header and copy the addressing and
// URL info we need.
mDNSexport void LNT_ConfigureRouterInfo(mDNS *m, const mDNSInterfaceID InterfaceID, const mDNSu8 *const data, const mDNSu16 len)
	{
	const mDNSu8 *ptr = data;
	const mDNSu8 *end = data + len;
	const mDNSu8 *stop = ptr;
	
	if (!mDNSIPPortIsZero(m->UPnPRouterPort)) return; // already have the info we need

	// The formatting of the HTTP header is not always the same when it comes to the placement of
	// the service and location strings, so we just look for each of them from the beginning for every response
	
	// figure out if this is a message from a service we care about
	while (ptr && ptr != end)
		{
		if ((*ptr & 0xDF) == 'W' && (strncasecmp((char*)ptr, "WANIPConnection:1", 17) == 0)) break;
		ptr++;
		}
	if (ptr == end)
		{
		ptr = data;
		while (ptr && ptr != end)
			{
			if ((*ptr & 0xDF) == 'W' && (strncasecmp((char*)ptr, "WANPPPConnection:1", 18) == 0)) break;
			ptr++;
			}
		}
	if (ptr == mDNSNULL || ptr == end) return;	// not a message we care about

	// find "Location:", starting from the beginning
	ptr = data;
	while (ptr && ptr != end)
		{
		if ((*ptr & 0xDF) == 'L' && (strncasecmp((char*)ptr, "Location:", 9) == 0)) break;			// find the first 'L'; is this Location? if not, keep looking
		ptr++;
		}
	if (ptr == mDNSNULL || ptr == end) 
		{
		mDNSASLLog((uuid_t *)&m->asl_uuid, "natt.legacy.ssdp", "failure", "Location", "");
		return;	// not a message we care about
		}
	ptr += 9; //Skip over 'Location:'
	while (*ptr == ' ' && ptr < end) ptr++; // skip over spaces
	if (ptr >= end) return;
	
	// find the end of the line
	for (stop = ptr; stop != end; stop++) { if (*stop == '\r') { end = stop; break; } }
	
	// fill in default port
	m->UPnPRouterPort = mDNSOpaque16fromIntVal(80);

	// free string pointers and set to NULL	
	if (m->UPnPRouterAddressString != mDNSNULL)
		{
		mDNSPlatformMemFree(m->UPnPRouterAddressString);
		m->UPnPRouterAddressString = mDNSNULL;
		}
	if (m->UPnPRouterURL != mDNSNULL)
		{
		mDNSPlatformMemFree(m->UPnPRouterURL);
		m->UPnPRouterURL = mDNSNULL; 
		}
	
	// the Router URL should look something like "/dyndev/uuid:0013-108c-4b3f0000f3dc"
	if (ParseHttpUrl(ptr, end, &m->UPnPRouterAddressString, &m->UPnPRouterPort, &m->UPnPRouterURL) != mStatus_NoError)
		{
		mDNSASLLog((uuid_t *)&m->asl_uuid, "natt.legacy.ssdp", "failure", "Parse URL", "");
		return;
		}

	m->UPnPInterfaceID = InterfaceID;

	if (m->UPnPRouterAddressString == mDNSNULL) 
		{
		mDNSASLLog((uuid_t *)&m->asl_uuid, "natt.legacy.ssdp", "failure", "Router address", "");
		LogMsg("LNT_ConfigureRouterInfo: UPnPRouterAddressString is NULL");
		}
	else LogInfo("LNT_ConfigureRouterInfo: Router address string [%s]", m->UPnPRouterAddressString);

	if (m->UPnPRouterURL == mDNSNULL) 
		{
		mDNSASLLog((uuid_t *)&m->asl_uuid, "natt.legacy.ssdp", "failure", "Router path", "");
		LogMsg("LNT_ConfigureRouterInfo: UPnPRouterURL is NULL");
		}
	else LogInfo("LNT_ConfigureRouterInfo: Router URL [%s]", m->UPnPRouterURL);

	LogInfo("LNT_ConfigureRouterInfo: Router port %d", mDNSVal16(m->UPnPRouterPort));
	LogInfo("LNT_ConfigureRouterInfo: Router interface %d", m->UPnPInterfaceID);

	// Don't need the SSDP socket anymore
	if (m->SSDPSocket) { debugf("LNT_ConfigureRouterInfo destroying SSDPSocket %p", &m->SSDPSocket); mDNSPlatformUDPClose(m->SSDPSocket); m->SSDPSocket = mDNSNULL; }

	mDNSASLLog((uuid_t *)&m->asl_uuid, "natt.legacy.ssdp", "success", "success", "");
	// now send message to get the device description
	GetDeviceDescription(m, &m->tcpDeviceInfo);
	}

mDNSexport void LNT_SendDiscoveryMsg(mDNS *m)
	{
	static const char msg[] =
		"M-SEARCH * HTTP/1.1\r\n"
		"Host:239.255.255.250:1900\r\n"
		"ST:urn:schemas-upnp-org:service:WAN%sConnection:1\r\n"
		"Man:\"ssdp:discover\"\r\n"
		"MX:3\r\n\r\n";
	static const mDNSAddr multicastDest = { mDNSAddrType_IPv4, { { { 239, 255, 255, 250 } } } };
	
	mDNSu8 *buf = (mDNSu8*)&m->omsg; //m->omsg is 8952 bytes, which is plenty
	unsigned int bufLen;
	
	if (!mDNSIPPortIsZero(m->UPnPRouterPort))
		{
		if (m->SSDPSocket) { debugf("LNT_SendDiscoveryMsg destroying SSDPSocket %p", &m->SSDPSocket); mDNSPlatformUDPClose(m->SSDPSocket); m->SSDPSocket = mDNSNULL; }
		if (mDNSIPPortIsZero(m->UPnPSOAPPort) && !m->tcpDeviceInfo.sock) GetDeviceDescription(m, &m->tcpDeviceInfo);
		return;
		}

	// Always query for WANIPConnection in the first SSDP packet
	if (m->retryIntervalGetAddr <= NATMAP_INIT_RETRY) m->SSDPWANPPPConnection = mDNSfalse;

	// Create message
	bufLen = mDNS_snprintf((char*)buf, sizeof(m->omsg), msg, m->SSDPWANPPPConnection ? "PPP" : "IP");

	debugf("LNT_SendDiscoveryMsg Router %.4a Current External Address %.4a", &m->Router.ip.v4, &m->ExternalAddress);

	if (!mDNSIPv4AddressIsZero(m->Router.ip.v4))
		{
		if (!m->SSDPSocket) { m->SSDPSocket = mDNSPlatformUDPSocket(m, zeroIPPort); debugf("LNT_SendDiscoveryMsg created SSDPSocket %p", &m->SSDPSocket); }
		mDNSPlatformSendUDP(m, buf, buf + bufLen, 0, m->SSDPSocket, &m->Router,     SSDPPort);
		mDNSPlatformSendUDP(m, buf, buf + bufLen, 0, m->SSDPSocket, &multicastDest, SSDPPort);
		}
		
	m->SSDPWANPPPConnection = !m->SSDPWANPPPConnection;
	}

mDNSexport void LNT_ClearState(mDNS *const m)
	{
	if (m->tcpAddrInfo.sock)   { mDNSPlatformTCPCloseConnection(m->tcpAddrInfo.sock);   m->tcpAddrInfo.sock   = mDNSNULL; }
	if (m->tcpDeviceInfo.sock) { mDNSPlatformTCPCloseConnection(m->tcpDeviceInfo.sock); m->tcpDeviceInfo.sock = mDNSNULL; }
	m->UPnPSOAPPort = m->UPnPRouterPort = zeroIPPort;	// Reset UPnP ports
	}

#endif /* _LEGACY_NAT_TRAVERSAL_ */
