dnssd_ipc.h revision afc86e3216439a9437ea54905853275111eac4e2
1/* -*- Mode: C; tab-width: 4 -*-
2 *
3 * Copyright (c) 2003-2004, Apple Computer, Inc. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 *
8 * 1.  Redistributions of source code must retain the above copyright notice,
9 *     this list of conditions and the following disclaimer.
10 * 2.  Redistributions in binary form must reproduce the above copyright notice,
11 *     this list of conditions and the following disclaimer in the documentation
12 *     and/or other materials provided with the distribution.
13 * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of its
14 *     contributors may be used to endorse or promote products derived from this
15 *     software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
18 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
21 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
26 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29#ifndef DNSSD_IPC_H
30#define DNSSD_IPC_H
31
32#include "dns_sd.h"
33
34//
35// Common cross platform services
36//
37#if defined(WIN32)
38#	include <winsock2.h>
39#	define dnssd_InvalidSocket	INVALID_SOCKET
40#	define dnssd_SocketValid(s) ((s) != INVALID_SOCKET)
41#	define dnssd_EWOULDBLOCK	WSAEWOULDBLOCK
42#	define dnssd_EINTR			WSAEINTR
43#	define dnssd_ECONNRESET		WSAECONNRESET
44#	define dnssd_sock_t			SOCKET
45#	define dnssd_socklen_t		int
46#	define dnssd_close(sock)	closesocket(sock)
47#	define dnssd_errno			WSAGetLastError()
48#	define dnssd_strerror(X)	win32_strerror(X)
49#	define ssize_t				int
50#	define getpid				_getpid
51#	define unlink				_unlink
52extern char *win32_strerror(int inErrorCode);
53#else
54#	include <sys/types.h>
55#	include <unistd.h>
56#ifdef __ANDROID__
57#	include <sys/socket.h>
58#endif
59#	include <sys/un.h>
60#	include <string.h>
61#	include <stdio.h>
62#	include <stdlib.h>
63#	include <sys/stat.h>
64#ifndef __ANDROID__
65#	include <sys/socket.h>
66#endif
67#	include <netinet/in.h>
68#	define dnssd_InvalidSocket	-1
69#	define dnssd_SocketValid(s) ((s) >= 0)
70#	define dnssd_EWOULDBLOCK	EWOULDBLOCK
71#	define dnssd_EINTR			EINTR
72#	define dnssd_ECONNRESET		ECONNRESET
73#	define dnssd_EPIPE			EPIPE
74#	define dnssd_sock_t			int
75#	define dnssd_socklen_t		unsigned int
76#	define dnssd_close(sock)	close(sock)
77#	define dnssd_errno			errno
78#	define dnssd_strerror(X)	strerror(X)
79#endif
80
81#if defined(USE_TCP_LOOPBACK)
82#	define AF_DNSSD				AF_INET
83#	define MDNS_TCP_SERVERADDR	"127.0.0.1"
84#	define MDNS_TCP_SERVERPORT	5354
85#	define LISTENQ				5
86#	define dnssd_sockaddr_t		struct sockaddr_in
87#else
88#	define AF_DNSSD				AF_LOCAL
89#	ifndef MDNS_UDS_SERVERPATH
90#		define MDNS_UDS_SERVERPATH	"/var/run/mDNSResponder"
91#	endif
92#	define LISTENQ				100
93    // longest legal control path length
94#	define MAX_CTLPATH			256
95#	define dnssd_sockaddr_t		struct sockaddr_un
96#endif
97
98// Compatibility workaround
99#ifndef AF_LOCAL
100#define	AF_LOCAL	AF_UNIX
101#endif
102
103// General UDS constants
104#define TXT_RECORD_INDEX ((uint32_t)(-1))	// record index for default text record
105
106// IPC data encoding constants and types
107#define VERSION 1
108#define IPC_FLAGS_NOREPLY 1	// set flag if no asynchronous replies are to be sent to client
109
110// Structure packing macro. If we're not using GNUC, it's not fatal. Most compilers naturally pack the on-the-wire
111// structures correctly anyway, so a plain "struct" is usually fine. In the event that structures are not packed
112// correctly, our compile-time assertion checks will catch it and prevent inadvertent generation of non-working code.
113#ifndef packedstruct
114 #if ((__GNUC__ > 2) || ((__GNUC__ == 2) && (__GNUC_MINOR__ >= 9)))
115  #define packedstruct struct __attribute__((__packed__))
116  #define packedunion  union  __attribute__((__packed__))
117 #else
118  #define packedstruct struct
119  #define packedunion  union
120 #endif
121#endif
122
123typedef enum
124    {
125    request_op_none = 0,	// No request yet received on this connection
126    connection_request = 1,	// connected socket via DNSServiceConnect()
127    reg_record_request,		// reg/remove record only valid for connected sockets
128    remove_record_request,
129    enumeration_request,
130    reg_service_request,
131    browse_request,
132    resolve_request,
133    query_request,
134    reconfirm_record_request,
135    add_record_request,
136    update_record_request,
137    setdomain_request,		// Up to here is in Tiger and B4W 1.0.3
138	getproperty_request,	// New in B4W 1.0.4
139    port_mapping_request,	// New in Leopard and B4W 2.0
140	addrinfo_request,
141	send_bpf,				// New in SL
142    sethost_request,
143	cancel_request = 63
144    } request_op_t;
145
146typedef enum
147    {
148    enumeration_reply_op = 64,
149    reg_service_reply_op,
150    browse_reply_op,
151    resolve_reply_op,
152    query_reply_op,
153    reg_record_reply_op,	// Up to here is in Tiger and B4W 1.0.3
154    getproperty_reply_op,	// New in B4W 1.0.4
155    port_mapping_reply_op,	// New in Leopard and B4W 2.0
156	addrinfo_reply_op,
157    sethost_reply,
158    } reply_op_t;
159
160#if defined(_WIN64)
161#	pragma pack(4)
162#endif
163
164// Define context object big enough to hold a 64-bit pointer,
165// to accomodate 64-bit clients communicating with 32-bit daemon.
166// There's no reason for the daemon to ever be a 64-bit process, but its clients might be
167typedef packedunion
168    {
169    void *context;
170    uint32_t u32[2];
171    } client_context_t;
172
173typedef packedstruct
174    {
175    uint32_t version;
176    uint32_t datalen;
177    uint32_t ipc_flags;
178    uint32_t op;		// request_op_t or reply_op_t
179    client_context_t client_context; // context passed from client, returned by server in corresponding reply
180    uint32_t reg_index;            // identifier for a record registered via DNSServiceRegisterRecord() on a
181    // socket connected by DNSServiceCreateConnection().  Must be unique in the scope of the connection, such that and
182    // index/socket pair uniquely identifies a record.  (Used to select records for removal by DNSServiceRemoveRecord())
183    } ipc_msg_hdr;
184
185// routines to write to and extract data from message buffers.
186// caller responsible for bounds checking.
187// ptr is the address of the pointer to the start of the field.
188// it is advanced to point to the next field, or the end of the message
189
190void put_uint32(const uint32_t l, char **ptr);
191uint32_t get_uint32(const char **ptr, const char *end);
192
193void put_uint16(uint16_t s, char **ptr);
194uint16_t get_uint16(const char **ptr, const char *end);
195
196#define put_flags put_uint32
197#define get_flags get_uint32
198
199#define put_error_code put_uint32
200#define get_error_code get_uint32
201
202int put_string(const char *str, char **ptr);
203int get_string(const char **ptr, const char *const end, char *buffer, int buflen);
204
205void put_rdata(const int rdlen, const unsigned char *rdata, char **ptr);
206const char *get_rdata(const char **ptr, const char *end, int rdlen);  // return value is rdata pointed to by *ptr -
207                                         // rdata is not copied from buffer.
208
209void ConvertHeaderBytes(ipc_msg_hdr *hdr);
210
211struct CompileTimeAssertionChecks_dnssd_ipc
212	{
213	// Check that the compiler generated our on-the-wire packet format structure definitions
214	// properly packed, without adding padding bytes to align fields on 32-bit or 64-bit boundaries.
215	char assert0[(sizeof(client_context_t) ==  8) ? 1 : -1];
216	char assert1[(sizeof(ipc_msg_hdr)      == 28) ? 1 : -1];
217	};
218
219#endif // DNSSD_IPC_H
220