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 # include <sys/un.h> 57 # include <string.h> 58 # include <stdio.h> 59 # include <stdlib.h> 60 # include <sys/stat.h> 61 # include <sys/socket.h> 62 # include <netinet/in.h> 63 # include <arpa/inet.h> 64 # define dnssd_InvalidSocket -1 65 # define dnssd_SocketValid(s) ((s) >= 0) 66 # define dnssd_EWOULDBLOCK EWOULDBLOCK 67 # define dnssd_EINTR EINTR 68 # define dnssd_ECONNRESET ECONNRESET 69 # define dnssd_EPIPE EPIPE 70 # define dnssd_sock_t int 71 # define dnssd_socklen_t unsigned int 72 # define dnssd_close(sock) close(sock) 73 # define dnssd_errno errno 74 # define dnssd_strerror(X) strerror(X) 75 #endif 76 77 #if defined(USE_TCP_LOOPBACK) 78 # define AF_DNSSD AF_INET 79 # define MDNS_TCP_SERVERADDR "127.0.0.1" 80 # define MDNS_TCP_SERVERPORT 5354 81 # define LISTENQ 5 82 # define dnssd_sockaddr_t struct sockaddr_in 83 #else 84 # define AF_DNSSD AF_LOCAL 85 # ifndef MDNS_UDS_SERVERPATH 86 # define MDNS_UDS_SERVERPATH "/var/run/mDNSResponder" 87 # endif 88 # define MDNS_UDS_SERVERPATH_ENVVAR "DNSSD_UDS_PATH" 89 # define LISTENQ 100 90 // longest legal control path length 91 # define MAX_CTLPATH 256 92 # define dnssd_sockaddr_t struct sockaddr_un 93 #endif 94 95 // Compatibility workaround 96 #ifndef AF_LOCAL 97 #define AF_LOCAL AF_UNIX 98 #endif 99 100 // General UDS constants 101 #define TXT_RECORD_INDEX ((uint32_t)(-1)) // record index for default text record 102 103 // IPC data encoding constants and types 104 #define VERSION 1 105 #define IPC_FLAGS_NOREPLY 1 // set flag if no asynchronous replies are to be sent to client 106 107 // Structure packing macro. If we're not using GNUC, it's not fatal. Most compilers naturally pack the on-the-wire 108 // structures correctly anyway, so a plain "struct" is usually fine. In the event that structures are not packed 109 // correctly, our compile-time assertion checks will catch it and prevent inadvertent generation of non-working code. 110 #ifndef packedstruct 111 #if ((__GNUC__ > 2) || ((__GNUC__ == 2) && (__GNUC_MINOR__ >= 9))) 112 #define packedstruct struct __attribute__((__packed__)) 113 #define packedunion union __attribute__((__packed__)) 114 #else 115 #define packedstruct struct 116 #define packedunion union 117 #endif 118 #endif 119 120 typedef enum 121 { 122 request_op_none = 0, // No request yet received on this connection 123 connection_request = 1, // connected socket via DNSServiceConnect() 124 reg_record_request, // reg/remove record only valid for connected sockets 125 remove_record_request, 126 enumeration_request, 127 reg_service_request, 128 browse_request, 129 resolve_request, 130 query_request, 131 reconfirm_record_request, 132 add_record_request, 133 update_record_request, 134 setdomain_request, // Up to here is in Tiger and B4W 1.0.3 135 getproperty_request, // New in B4W 1.0.4 136 port_mapping_request, // New in Leopard and B4W 2.0 137 addrinfo_request, 138 send_bpf, // New in SL 139 getpid_request, 140 release_request, 141 connection_delegate_request, 142 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 } reply_op_t; 158 159 #if defined(_WIN64) 160 # pragma pack(push,4) 161 #elif !defined(__GNUC__) 162 # pragma pack(1) 163 #endif 164 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 168 typedef packedunion 169 { 170 void *context; 171 uint32_t u32[2]; 172 } client_context_t; 173 174 typedef packedstruct 175 { 176 uint32_t version; 177 uint32_t datalen; 178 uint32_t ipc_flags; 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()) 184 } ipc_msg_hdr; 185 186 #if defined(_WIN64) 187 # pragma pack(pop) 188 #elif !defined(__GNUC__) 189 # pragma pack() 190 #endif 191 192 // routines to write to and extract data from message buffers. 193 // caller responsible for bounds checking. 194 // ptr is the address of the pointer to the start of the field. 195 // it is advanced to point to the next field, or the end of the message 196 197 void put_uint32(const uint32_t l, char **ptr); 198 uint32_t get_uint32(const char **ptr, const char *end); 199 200 void put_uint16(uint16_t s, char **ptr); 201 uint16_t get_uint16(const char **ptr, const char *end); 202 203 #define put_flags put_uint32 204 #define get_flags get_uint32 205 206 #define put_error_code put_uint32 207 #define get_error_code get_uint32 208 209 int put_string(const char *str, char **ptr); 210 int get_string(const char **ptr, const char *const end, char *buffer, int buflen); 211 212 void put_rdata(const int rdlen, const unsigned char *rdata, char **ptr); 213 const char *get_rdata(const char **ptr, const char *end, int rdlen); // return value is rdata pointed to by *ptr - 214 // rdata is not copied from buffer. 215 216 void ConvertHeaderBytes(ipc_msg_hdr *hdr); 217 218 struct CompileTimeAssertionChecks_dnssd_ipc 219 { 220 // Check that the compiler generated our on-the-wire packet format structure definitions 221 // properly packed, without adding padding bytes to align fields on 32-bit or 64-bit boundaries. 222 char assert0[(sizeof(client_context_t) == 8) ? 1 : -1]; 223 char assert1[(sizeof(ipc_msg_hdr) == 28) ? 1 : -1]; 224 }; 225 226 #endif // DNSSD_IPC_H 227