/* -*- Mode: C; tab-width: 4 -*-
 *
 * Copyright (c) 2003-2004, Apple Computer, Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * 1.  Redistributions of source code must retain the above copyright notice,
 *     this list of conditions and the following disclaimer.
 * 2.  Redistributions in binary form must reproduce the above copyright notice,
 *     this list of conditions and the following disclaimer in the documentation
 *     and/or other materials provided with the distribution.
 * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of its
 *     contributors may be used to endorse or promote products derived from this
 *     software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#ifndef DNSSD_IPC_H
#define DNSSD_IPC_H

#include "dns_sd.h"

//
// Common cross platform services
//
#if defined(WIN32)
#	include <winsock2.h>
#	define dnssd_InvalidSocket	INVALID_SOCKET
#	define dnssd_SocketValid(s) ((s) != INVALID_SOCKET)
#	define dnssd_EWOULDBLOCK	WSAEWOULDBLOCK
#	define dnssd_EINTR			WSAEINTR
#	define dnssd_sock_t			SOCKET
#	define dnssd_socklen_t		int
#	define dnssd_close(sock)	closesocket(sock)
#	define dnssd_errno			WSAGetLastError()
#	define dnssd_strerror(X)	win32_strerror(X)
#	define ssize_t				int
#	define getpid				_getpid
#	define unlink				_unlink
extern char *win32_strerror(int inErrorCode);
#else
#	include <sys/types.h>
#	include <unistd.h>
#	include <sys/un.h>
#	include <string.h>
#	include <stdio.h>
#	include <stdlib.h>
#	include <sys/stat.h>
#	include <sys/socket.h>
#	include <netinet/in.h>
#	define dnssd_InvalidSocket	-1
#	define dnssd_SocketValid(s) ((s) >= 0)
#	define dnssd_EWOULDBLOCK	EWOULDBLOCK
#	define dnssd_EINTR			EINTR
#	define dnssd_EPIPE			EPIPE
#	define dnssd_sock_t			int
#	define dnssd_socklen_t		unsigned int
#	define dnssd_close(sock)	close(sock)
#	define dnssd_errno			errno
#	define dnssd_strerror(X)	strerror(X)
#endif

#if defined(USE_TCP_LOOPBACK)
#	define AF_DNSSD				AF_INET
#	define MDNS_TCP_SERVERADDR	"127.0.0.1"
#	define MDNS_TCP_SERVERPORT	5354
#	define LISTENQ				5
#	define dnssd_sockaddr_t		struct sockaddr_in
#else
#	define AF_DNSSD				AF_LOCAL
#	ifndef MDNS_UDS_SERVERPATH
#		define MDNS_UDS_SERVERPATH	"/var/run/mDNSResponder"
#	endif
#	define LISTENQ				100
    // longest legal control path length
#	define MAX_CTLPATH			256
#	define dnssd_sockaddr_t		struct sockaddr_un
#endif

// Compatibility workaround
#ifndef AF_LOCAL
#define	AF_LOCAL	AF_UNIX
#endif

// General UDS constants
#define TXT_RECORD_INDEX ((uint32_t)(-1))	// record index for default text record

// IPC data encoding constants and types
#define VERSION 1
#define IPC_FLAGS_NOREPLY 1	// set flag if no asynchronous replies are to be sent to client

// Structure packing macro. If we're not using GNUC, it's not fatal. Most compilers naturally pack the on-the-wire
// structures correctly anyway, so a plain "struct" is usually fine. In the event that structures are not packed
// correctly, our compile-time assertion checks will catch it and prevent inadvertent generation of non-working code.
#ifndef packedstruct
 #if ((__GNUC__ > 2) || ((__GNUC__ == 2) && (__GNUC_MINOR__ >= 9)))
  #define packedstruct struct __attribute__((__packed__))
  #define packedunion  union  __attribute__((__packed__))
 #else
  #define packedstruct struct
  #define packedunion  union
 #endif
#endif

typedef enum
    {
    request_op_none = 0,	// No request yet received on this connection
    connection_request = 1,	// connected socket via DNSServiceCreateConnection()
    reg_record_request,		// reg/remove record only valid for connected sockets
    remove_record_request,
    enumeration_request,
    reg_service_request,
    browse_request,
    resolve_request,
    query_request,
    reconfirm_record_request,
    add_record_request,
    update_record_request,
    setdomain_request,		// Up to here is in Tiger and B4W 1.0.3
	getproperty_request,	// New in B4W 1.0.4
    port_mapping_request,	// New in Leopard and B4W 2.0
	addrinfo_request,
	send_bpf,				// New in SL

	cancel_request = 63
    } request_op_t;

typedef enum
    {
    enumeration_reply_op = 64,
    reg_service_reply_op,
    browse_reply_op,
    resolve_reply_op,
    query_reply_op,
    reg_record_reply_op,	// Up to here is in Tiger and B4W 1.0.3
    getproperty_reply_op,	// New in B4W 1.0.4
    port_mapping_reply_op,	// New in Leopard and B4W 2.0
	addrinfo_reply_op
    } reply_op_t;

#if defined(_WIN64)
#	pragma pack(4)
#endif

// Define context object big enough to hold a 64-bit pointer,
// to accomodate 64-bit clients communicating with 32-bit daemon.
// There's no reason for the daemon to ever be a 64-bit process, but its clients might be
typedef packedunion
    {
    void *context;
    uint32_t u32[2];
    } client_context_t;

typedef packedstruct
    {
    uint32_t version;
    uint32_t datalen;
    uint32_t ipc_flags;
    uint32_t op;		// request_op_t or reply_op_t
    client_context_t client_context; // context passed from client, returned by server in corresponding reply
    uint32_t reg_index;            // identifier for a record registered via DNSServiceRegisterRecord() on a
    // socket connected by DNSServiceCreateConnection().  Must be unique in the scope of the connection, such that and
    // index/socket pair uniquely identifies a record.  (Used to select records for removal by DNSServiceRemoveRecord())
    } ipc_msg_hdr;

// routines to write to and extract data from message buffers.
// caller responsible for bounds checking.
// ptr is the address of the pointer to the start of the field.
// it is advanced to point to the next field, or the end of the message

void put_uint32(const uint32_t l, char **ptr);
uint32_t get_uint32(const char **ptr, const char *end);

void put_uint16(uint16_t s, char **ptr);
uint16_t get_uint16(const char **ptr, const char *end);

#define put_flags put_uint32
#define get_flags get_uint32

#define put_error_code put_uint32
#define get_error_code get_uint32

int put_string(const char *str, char **ptr);
int get_string(const char **ptr, const char *const end, char *buffer, int buflen);

void put_rdata(const int rdlen, const unsigned char *rdata, char **ptr);
const char *get_rdata(const char **ptr, const char *end, int rdlen);  // return value is rdata pointed to by *ptr -
                                         // rdata is not copied from buffer.

void ConvertHeaderBytes(ipc_msg_hdr *hdr);

struct CompileTimeAssertionChecks_dnssd_ipc
	{
	// Check that the compiler generated our on-the-wire packet format structure definitions
	// properly packed, without adding padding bytes to align fields on 32-bit or 64-bit boundaries.
	char assert0[(sizeof(client_context_t) ==  8) ? 1 : -1];
	char assert1[(sizeof(ipc_msg_hdr)      == 28) ? 1 : -1];
	};

#endif // DNSSD_IPC_H
