1 /* -*- Mode: C; tab-width: 4 -*-
3 * Copyright (c) 2003-2020 Apple Inc. All rights reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
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 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.
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.
35 // Common cross platform services
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_socklen_t int
45 # define dnssd_close(sock) closesocket(sock)
46 # define dnssd_errno WSAGetLastError()
47 # define dnssd_strerror(X) win32_strerror(X)
49 # define getpid _getpid
50 # define unlink _unlink
51 extern char *win32_strerror(int inErrorCode
);
53 # include <sys/types.h>
59 # include <sys/stat.h>
60 # include <sys/socket.h>
61 # include <netinet/in.h>
62 # include <arpa/inet.h>
63 # define dnssd_InvalidSocket -1
64 # define dnssd_SocketValid(s) ((s) >= 0)
65 # define dnssd_EWOULDBLOCK EWOULDBLOCK
66 # define dnssd_EINTR EINTR
67 # define dnssd_ECONNRESET ECONNRESET
68 # define dnssd_EPIPE EPIPE
69 # define dnssd_socklen_t unsigned int
70 # define dnssd_close(sock) close(sock)
71 # define dnssd_errno errno
72 # define dnssd_strerror(X) strerror(X)
75 #if defined(USE_TCP_LOOPBACK)
76 # define AF_DNSSD AF_INET
77 # define MDNS_TCP_SERVERADDR "127.0.0.1"
78 # define MDNS_TCP_SERVERPORT 5354
80 # define dnssd_sockaddr_t struct sockaddr_in
82 # define AF_DNSSD AF_LOCAL
83 # ifndef MDNS_UDS_SERVERPATH
84 # define MDNS_UDS_SERVERPATH "/var/run/mDNSResponder"
86 # define MDNS_UDS_SERVERPATH_ENVVAR "DNSSD_UDS_PATH"
88 // longest legal control path length
89 # define MAX_CTLPATH (sizeof(((struct sockaddr_un*)0)->sun_path))
90 # define dnssd_sockaddr_t struct sockaddr_un
93 // Compatibility workaround
95 #define AF_LOCAL AF_UNIX
98 // General UDS constants
99 #define TXT_RECORD_INDEX ((uint32_t)(-1)) // record index for default text record
101 // IPC data encoding constants and types
103 #define IPC_FLAGS_NOREPLY (1U << 0) // Set flag if no asynchronous replies are to be sent to client.
104 #define IPC_FLAGS_TRAILING_TLVS (1U << 1) // Set flag if TLVs follow the standard request data.
106 #define IPC_TLV_TYPE_RESOLVER_CONFIG_PLIST_DATA 1 // An nw_resolver_config as a binary property list.
107 #define IPC_TLV_TYPE_REQUIRE_PRIVACY 2 // A uint8. Non-zero means privacy is required, zero means not required.
109 // Structure packing macro. If we're not using GNUC, it's not fatal. Most compilers naturally pack the on-the-wire
110 // structures correctly anyway, so a plain "struct" is usually fine. In the event that structures are not packed
111 // correctly, our compile-time assertion checks will catch it and prevent inadvertent generation of non-working code.
113 #if ((__GNUC__ > 2) || ((__GNUC__ == 2) && (__GNUC_MINOR__ >= 9)))
114 #define packedstruct struct __attribute__((__packed__))
115 #define packedunion union __attribute__((__packed__))
117 #define packedstruct struct
118 #define packedunion union
124 request_op_none
= 0, // No request yet received on this connection
125 connection_request
= 1, // connected socket via DNSServiceConnect()
126 reg_record_request
, // reg/remove record only valid for connected sockets
127 remove_record_request
,
133 reconfirm_record_request
,
135 update_record_request
,
136 setdomain_request
, // Up to here is in Tiger and B4W 1.0.3
137 getproperty_request
, // New in B4W 1.0.4
138 port_mapping_request
, // New in Leopard and B4W 2.0
140 send_bpf
, // New in SL
143 connection_delegate_request
,
150 enumeration_reply_op
= 64,
151 reg_service_reply_op
,
155 reg_record_reply_op
, // Up to here is in Tiger and B4W 1.0.3
156 getproperty_reply_op
, // New in B4W 1.0.4
157 port_mapping_reply_op
, // New in Leopard and B4W 2.0
162 # pragma pack(push,4)
165 // Define context object big enough to hold a 64-bit pointer,
166 // to accomodate 64-bit clients communicating with 32-bit daemon.
167 // There's no reason for the daemon to ever be a 64-bit process, but its clients might be
179 uint32_t op
; // request_op_t or reply_op_t
180 client_context_t client_context
; // context passed from client, returned by server in corresponding reply
181 uint32_t reg_index
; // identifier for a record registered via DNSServiceRegisterRecord() on a
182 // socket connected by DNSServiceCreateConnection(). Must be unique in the scope of the connection, such that and
183 // index/socket pair uniquely identifies a record. (Used to select records for removal by DNSServiceRemoveRecord())
190 // routines to write to and extract data from message buffers.
191 // caller responsible for bounds checking.
192 // ptr is the address of the pointer to the start of the field.
193 // it is advanced to point to the next field, or the end of the message
195 void put_uint32(const uint32_t l
, char **ptr
);
196 uint32_t get_uint32(const char **ptr
, const char *end
);
198 void put_uint16(uint16_t s
, char **ptr
);
199 uint16_t get_uint16(const char **ptr
, const char *end
);
201 #define put_flags put_uint32
202 #define get_flags get_uint32
204 #define put_error_code put_uint32
205 #define get_error_code get_uint32
207 int put_string(const char *str
, char **ptr
);
208 int get_string(const char **ptr
, const char *const end
, char *buffer
, int buflen
);
210 void put_rdata(const int rdlen
, const unsigned char *rdata
, char **ptr
);
211 const char *get_rdata(const char **ptr
, const char *end
, int rdlen
); // return value is rdata pointed to by *ptr -
212 // rdata is not copied from buffer.
214 #if APPLE_OSX_mDNSResponder
215 size_t get_required_tlv16_length(const uint16_t valuelen
);
216 void put_tlv16(const uint16_t type
, const uint16_t length
, const uint8_t *value
, char **ptr
);
219 void ConvertHeaderBytes(ipc_msg_hdr
*hdr
);
221 struct CompileTimeAssertionChecks_dnssd_ipc
223 // Check that the compiler generated our on-the-wire packet format structure definitions
224 // properly packed, without adding padding bytes to align fields on 32-bit or 64-bit boundaries.
225 char assert0
[(sizeof(client_context_t
) == 8) ? 1 : -1];
226 char assert1
[(sizeof(ipc_msg_hdr
) == 28) ? 1 : -1];
229 #endif // DNSSD_IPC_H