1/* -*- Mode: C; tab-width: 4 -*- 2 * 3 * Copyright (c) 2003-2015 Apple 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 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_socklen_t int 45# define dnssd_close(sock) closesocket(sock) 46# define dnssd_errno WSAGetLastError() 47# define dnssd_strerror(X) win32_strerror(X) 48# define ssize_t int 49# define getpid _getpid 50# define unlink _unlink 51extern char *win32_strerror(int inErrorCode); 52#else 53# include <sys/types.h> 54# include <unistd.h> 55# include <sys/un.h> 56# include <string.h> 57# include <stdio.h> 58# include <stdlib.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) 73#endif 74 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 79# define LISTENQ 5 80# define dnssd_sockaddr_t struct sockaddr_in 81#else 82# define AF_DNSSD AF_LOCAL 83# ifndef MDNS_UDS_SERVERPATH 84# define MDNS_UDS_SERVERPATH "/var/run/mDNSResponder" 85# endif 86# define MDNS_UDS_SERVERPATH_ENVVAR "DNSSD_UDS_PATH" 87# define LISTENQ 100 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 91#endif 92 93// Compatibility workaround 94#ifndef AF_LOCAL 95#define AF_LOCAL AF_UNIX 96#endif 97 98// General UDS constants 99#define TXT_RECORD_INDEX ((uint32_t)(-1)) // record index for default text record 100 101// IPC data encoding constants and types 102#define VERSION 1 103#define IPC_FLAGS_NOREPLY 1 // set flag if no asynchronous replies are to be sent to client 104 105// Structure packing macro. If we're not using GNUC, it's not fatal. Most compilers naturally pack the on-the-wire 106// structures correctly anyway, so a plain "struct" is usually fine. In the event that structures are not packed 107// correctly, our compile-time assertion checks will catch it and prevent inadvertent generation of non-working code. 108#ifndef packedstruct 109 #if ((__GNUC__ > 2) || ((__GNUC__ == 2) && (__GNUC_MINOR__ >= 9))) 110 #define packedstruct struct __attribute__((__packed__)) 111 #define packedunion union __attribute__((__packed__)) 112 #else 113 #define packedstruct struct 114 #define packedunion union 115 #endif 116#endif 117 118typedef enum 119{ 120 request_op_none = 0, // No request yet received on this connection 121 connection_request = 1, // connected socket via DNSServiceConnect() 122 reg_record_request, // reg/remove record only valid for connected sockets 123 remove_record_request, 124 enumeration_request, 125 reg_service_request, 126 browse_request, 127 resolve_request, 128 query_request, 129 reconfirm_record_request, 130 add_record_request, 131 update_record_request, 132 setdomain_request, // Up to here is in Tiger and B4W 1.0.3 133 getproperty_request, // New in B4W 1.0.4 134 port_mapping_request, // New in Leopard and B4W 2.0 135 addrinfo_request, 136 send_bpf, // New in SL 137 getpid_request, 138 release_request, 139 connection_delegate_request, 140 141 cancel_request = 63 142} request_op_t; 143 144typedef enum 145{ 146 enumeration_reply_op = 64, 147 reg_service_reply_op, 148 browse_reply_op, 149 resolve_reply_op, 150 query_reply_op, 151 reg_record_reply_op, // Up to here is in Tiger and B4W 1.0.3 152 getproperty_reply_op, // New in B4W 1.0.4 153 port_mapping_reply_op, // New in Leopard and B4W 2.0 154 addrinfo_reply_op 155} reply_op_t; 156 157#if defined(_WIN64) 158# pragma pack(push,4) 159#endif 160 161// Define context object big enough to hold a 64-bit pointer, 162// to accomodate 64-bit clients communicating with 32-bit daemon. 163// There's no reason for the daemon to ever be a 64-bit process, but its clients might be 164typedef packedunion 165{ 166 void *context; 167 uint32_t u32[2]; 168} client_context_t; 169 170typedef packedstruct 171{ 172 uint32_t version; 173 uint32_t datalen; 174 uint32_t ipc_flags; 175 uint32_t op; // request_op_t or reply_op_t 176 client_context_t client_context; // context passed from client, returned by server in corresponding reply 177 uint32_t reg_index; // identifier for a record registered via DNSServiceRegisterRecord() on a 178 // socket connected by DNSServiceCreateConnection(). Must be unique in the scope of the connection, such that and 179 // index/socket pair uniquely identifies a record. (Used to select records for removal by DNSServiceRemoveRecord()) 180} ipc_msg_hdr; 181 182#if defined(_WIN64) 183# pragma pack(pop) 184#endif 185 186// routines to write to and extract data from message buffers. 187// caller responsible for bounds checking. 188// ptr is the address of the pointer to the start of the field. 189// it is advanced to point to the next field, or the end of the message 190 191// Keep these out of the general namespace -- they're only used internally 192// by the library. 193#define put_uint32 __dnssd_ipc_put_uint32 194#define get_uint32 __dnssd_ipc_get_uint32 195#define put_uint16 __dnssd_ipc_put_uint16 196#define get_uint16 __dnssd_ipc_get_uint16 197#define put_string __dnssd_ipc_put_string 198#define get_string __dnssd_ipc_get_string 199#define put_rdata __dnssd_ipc_put_rdata 200#define get_rdata __dnssd_ipc_get_rdata 201#define ConvertHeaderBytes __dnssd_ipc_ConvertHeaderBytes 202 203void put_uint32(const uint32_t l, char **ptr); 204uint32_t get_uint32(const char **ptr, const char *end); 205 206void put_uint16(uint16_t s, char **ptr); 207uint16_t get_uint16(const char **ptr, const char *end); 208 209#define put_flags put_uint32 210#define get_flags get_uint32 211 212#define put_error_code put_uint32 213#define get_error_code get_uint32 214 215int put_string(const char *str, char **ptr); 216int get_string(const char **ptr, const char *const end, char *buffer, int buflen); 217 218void put_rdata(const int rdlen, const unsigned char *rdata, char **ptr); 219const char *get_rdata(const char **ptr, const char *end, int rdlen); // return value is rdata pointed to by *ptr - 220// rdata is not copied from buffer. 221 222void ConvertHeaderBytes(ipc_msg_hdr *hdr); 223 224struct CompileTimeAssertionChecks_dnssd_ipc 225{ 226 // Check that the compiler generated our on-the-wire packet format structure definitions 227 // properly packed, without adding padding bytes to align fields on 32-bit or 64-bit boundaries. 228#ifndef __lint__ 229 char assert0[(sizeof(client_context_t) == 8) ? 1 : -1]; 230 char assert1[(sizeof(ipc_msg_hdr) == 28) ? 1 : -1]; 231#endif 232}; 233 234#endif // DNSSD_IPC_H 235