• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
52 extern 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 
123 typedef 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 
146 typedef 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
167 typedef packedunion
168     {
169     void *context;
170     uint32_t u32[2];
171     } client_context_t;
172 
173 typedef 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 
190 void put_uint32(const uint32_t l, char **ptr);
191 uint32_t get_uint32(const char **ptr, const char *end);
192 
193 void put_uint16(uint16_t s, char **ptr);
194 uint16_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 
202 int put_string(const char *str, char **ptr);
203 int get_string(const char **ptr, const char *const end, char *buffer, int buflen);
204 
205 void put_rdata(const int rdlen, const unsigned char *rdata, char **ptr);
206 const 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 
209 void ConvertHeaderBytes(ipc_msg_hdr *hdr);
210 
211 struct 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