summaryrefslogtreecommitdiff
path: root/sd/source/ui/remotecontrol/mDNSResponder/dnssd_ipc.h
blob: 37bae8a1c431ad926ab7fb5359587dc906161bb4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
/* -*- Mode: C; tab-width: 4 -*-
 *
 * Copyright (c) 2003-2004, Apple Computer, Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * 1.  Redistributions of source code must retain the above copyright notice,
 *     this list of conditions and the following disclaimer.
 * 2.  Redistributions in binary form must reproduce the above copyright notice,
 *     this list of conditions and the following disclaimer in the documentation
 *     and/or other materials provided with the distribution.
 * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of its
 *     contributors may be used to endorse or promote products derived from this
 *     software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#ifndef INCLUDED_SD_SOURCE_UI_REMOTECONTROL_MDNSRESPONDER_DNSSD_IPC_H
#define INCLUDED_SD_SOURCE_UI_REMOTECONTROL_MDNSRESPONDER_DNSSD_IPC_H


//
// Common cross platform services
//
#if defined(WIN32)
#   include <winsock2.h>
#endif

#include "dns_sd.h"

#if defined(WIN32)
#   define dnssd_InvalidSocket  INVALID_SOCKET
#   define dnssd_SocketValid(s) ((s) != INVALID_SOCKET)
#   define dnssd_EWOULDBLOCK    WSAEWOULDBLOCK
#   define dnssd_EINTR          WSAEINTR
#   define dnssd_ECONNRESET     WSAECONNRESET
#   define dnssd_sock_t         SOCKET
#   define dnssd_socklen_t      int
#   define dnssd_close(sock)    closesocket(sock)
#   define dnssd_errno          WSAGetLastError()
#   define dnssd_strerror(X)    win32_strerror(X)
#   define ssize_t              int
#   define getpid               _getpid
#   define unlink               _unlink
extern char *win32_strerror(int inErrorCode);
#else
#   include <sys/types.h>
#   include <unistd.h>
#   include <sys/un.h>
#   include <string.h>
#   include <stdio.h>
#   include <stdlib.h>
#   include <sys/stat.h>
#   include <sys/socket.h>
#   include <netinet/in.h>
#   include <arpa/inet.h>
#   define dnssd_InvalidSocket  -1
#   define dnssd_SocketValid(s) ((s) >= 0)
#   define dnssd_EWOULDBLOCK    EWOULDBLOCK
#   define dnssd_EINTR          EINTR
#   define dnssd_ECONNRESET     ECONNRESET
#   define dnssd_EPIPE          EPIPE
#   define dnssd_sock_t         int
#   define dnssd_socklen_t      unsigned int
#   define dnssd_close(sock)    close(sock)
#   define dnssd_errno          errno
#   define dnssd_strerror(X)    strerror(X)
#endif

#if defined(USE_TCP_LOOPBACK)
#   define AF_DNSSD             AF_INET
#   define MDNS_TCP_SERVERADDR  "127.0.0.1"
#   define MDNS_TCP_SERVERPORT  5354
#   define LISTENQ              5
#   define dnssd_sockaddr_t     struct sockaddr_in
#else
#   define AF_DNSSD             AF_LOCAL
#   ifndef MDNS_UDS_SERVERPATH
#       define MDNS_UDS_SERVERPATH  "/var/run/mDNSResponder"
#   endif
#   define LISTENQ              100
// longest legal control path length
#   define MAX_CTLPATH          256
#   define dnssd_sockaddr_t     struct sockaddr_un
#endif

// Compatibility workaround
#ifndef AF_LOCAL
#define AF_LOCAL    AF_UNIX
#endif

// General UDS constants
#define TXT_RECORD_INDEX ((uint32_t)(-1))   // record index for default text record

// IPC data encoding constants and types
#define VERSION 1
#define IPC_FLAGS_NOREPLY 1 // set flag if no asynchronous replies are to be sent to client

// Structure packing macro. If we're not using GNUC, it's not fatal. Most compilers naturally pack the on-the-wire
// structures correctly anyway, so a plain "struct" is usually fine. In the event that structures are not packed
// correctly, our compile-time assertion checks will catch it and prevent inadvertent generation of non-working code.
#ifndef packedstruct
 #if ((__GNUC__ > 2) || ((__GNUC__ == 2) && (__GNUC_MINOR__ >= 9)))
  #define packedstruct struct __attribute__((__packed__))
  #define packedunion  union  __attribute__((__packed__))
 #else
  #define packedstruct struct
  #define packedunion  union
 #endif
#endif

typedef enum
{
    request_op_none = 0,    // No request yet received on this connection
    connection_request = 1, // connected socket via DNSServiceConnect()
    reg_record_request,     // reg/remove record only valid for connected sockets
    remove_record_request,
    enumeration_request,
    reg_service_request,
    browse_request,
    resolve_request,
    query_request,
    reconfirm_record_request,
    add_record_request,
    update_record_request,
    setdomain_request,      // Up to here is in Tiger and B4W 1.0.3
    getproperty_request,    // New in B4W 1.0.4
    port_mapping_request,   // New in Leopard and B4W 2.0
    addrinfo_request,
    send_bpf,               // New in SL
    release_request,

    cancel_request = 63
} request_op_t;

typedef enum
{
    enumeration_reply_op = 64,
    reg_service_reply_op,
    browse_reply_op,
    resolve_reply_op,
    query_reply_op,
    reg_record_reply_op,    // Up to here is in Tiger and B4W 1.0.3
    getproperty_reply_op,   // New in B4W 1.0.4
    port_mapping_reply_op,  // New in Leopard and B4W 2.0
    addrinfo_reply_op
} reply_op_t;

#if defined(_WIN64)
#   pragma pack(push,4)
#endif

// Define context object big enough to hold a 64-bit pointer,
// to accomodate 64-bit clients communicating with 32-bit daemon.
// There's no reason for the daemon to ever be a 64-bit process, but its clients might be
typedef packedunion
{
    void *context;
    uint32_t u32[2];
} client_context_t;

typedef packedstruct
{
    uint32_t version;
    uint32_t datalen;
    uint32_t ipc_flags;
    uint32_t op;        // request_op_t or reply_op_t
    client_context_t client_context; // context passed from client, returned by server in corresponding reply
    uint32_t reg_index;            // identifier for a record registered via DNSServiceRegisterRecord() on a
    // socket connected by DNSServiceCreateConnection().  Must be unique in the scope of the connection, such that and
    // index/socket pair uniquely identifies a record.  (Used to select records for removal by DNSServiceRemoveRecord())
} ipc_msg_hdr;

#if defined(_WIN64)
#   pragma pack(pop)
#endif

// routines to write to and extract data from message buffers.
// caller responsible for bounds checking.
// ptr is the address of the pointer to the start of the field.
// it is advanced to point to the next field, or the end of the message

void put_uint32(const uint32_t l, char **ptr);
uint32_t get_uint32(const char **ptr, const char *end);

void put_uint16(uint16_t s, char **ptr);
uint16_t get_uint16(const char **ptr, const char *end);

#define put_flags put_uint32
#define get_flags get_uint32

#define put_error_code put_uint32
#define get_error_code get_uint32

int put_string(const char *str, char **ptr);
int get_string(const char **ptr, const char *const end, char *buffer, int buflen);

void put_rdata(const int rdlen, const unsigned char *rdata, char **ptr);
const char *get_rdata(const char **ptr, const char *end, int rdlen);  // return value is rdata pointed to by *ptr -
// rdata is not copied from buffer.

void ConvertHeaderBytes(ipc_msg_hdr *hdr);

struct CompileTimeAssertionChecks_dnssd_ipc
{
    // Check that the compiler generated our on-the-wire packet format structure definitions
    // properly packed, without adding padding bytes to align fields on 32-bit or 64-bit boundaries.
    char assert0[(sizeof(client_context_t) ==  8) ? 1 : -1];
    char assert1[(sizeof(ipc_msg_hdr)      == 28) ? 1 : -1];
};

#endif // INCLUDED_SD_SOURCE_UI_REMOTECONTROL_MDNSRESPONDER_DNSSD_IPC_H