]> git.saurik.com Git - apple/mdnsresponder.git/blob - mDNSMacOSX/helper-stubs.c
mDNSResponder-878.200.35.tar.gz
[apple/mdnsresponder.git] / mDNSMacOSX / helper-stubs.c
1 /* -*- Mode: C; tab-width: 4 -*-
2 *
3 * Copyright (c) 2007-2018 Apple Inc. All rights reserved.
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18 #include <mach/mach.h>
19 #include <mach/mach_error.h>
20 #include <mach/vm_map.h>
21 #include <servers/bootstrap.h>
22 #include <IOKit/IOReturn.h>
23 #include <CoreFoundation/CoreFoundation.h>
24 #include "mDNSDebug.h"
25 #include "helper.h"
26 #include <dispatch/dispatch.h>
27 #include <arpa/inet.h>
28 #include <xpc/private.h>
29 #include <Block.h>
30
31 //
32 // Implementation Notes about the HelperQueue:
33 //
34 // To prevent blocking the main queue, all communications with mDNSResponderHelper should happen on
35 // HelperQueue. There are a few calls which are still synchronous and needs to be handled separately
36 // case by case.
37 //
38 // When spawning off the work to the HelperQueue, any arguments that are pointers need to be copied
39 // explicitly as they may cease to exist after the call returns. From within the block that is scheduled,
40 // arrays defined on the stack can't be referenced and hence it is enclosed them in a struct. If the array is
41 // an argument to the function, the blocks can reference them as they are passed in as pointers. But care should
42 // be taken to copy them locally as they may cease to exist when the function returns.
43 //
44
45
46 //*************************************************************************************************************
47 // Globals
48 static dispatch_queue_t HelperQueue;
49 static xpc_connection_t helper_xpc_conn = NULL;
50
51 static int64_t maxwait_secs = 5LL;
52
53 #define mDNSHELPER_DEBUG LogOperation
54
55 //*************************************************************************************************************
56 // Utility Functions
57
58 static void HelperLog(const char *prefix, xpc_object_t o)
59 {
60 char *desc = xpc_copy_description(o);
61 mDNSHELPER_DEBUG("HelperLog %s: %s", prefix, desc);
62 free(desc);
63 }
64
65 //*************************************************************************************************************
66 // XPC Funcs:
67 //*************************************************************************************************************
68
69
70 mDNSlocal void Init_Connection(const char *servname)
71 {
72 helper_xpc_conn = xpc_connection_create_mach_service(servname, HelperQueue, XPC_CONNECTION_MACH_SERVICE_PRIVILEGED);
73
74 xpc_connection_set_event_handler(helper_xpc_conn, ^(xpc_object_t event)
75 {
76 mDNSHELPER_DEBUG("Init_Connection xpc: [%s] \n", xpc_dictionary_get_string(event, XPC_ERROR_KEY_DESCRIPTION));
77 });
78
79 xpc_connection_resume(helper_xpc_conn);
80 }
81
82 mDNSlocal int SendDict_ToServer(xpc_object_t msg)
83 {
84 __block int errorcode = kHelperErr_NoResponse;
85
86 HelperLog("SendDict_ToServer Sending msg to Daemon", msg);
87
88 dispatch_semaphore_t sem = dispatch_semaphore_create(0);
89 dispatch_retain(sem); // for the block below
90
91 xpc_connection_send_message_with_reply(helper_xpc_conn, msg, HelperQueue, ^(xpc_object_t recv_msg)
92 {
93 xpc_type_t type = xpc_get_type(recv_msg);
94
95 if (type == XPC_TYPE_DICTIONARY)
96 {
97 HelperLog("SendDict_ToServer Received reply msg from Daemon", recv_msg);
98 uint64_t reply_status = xpc_dictionary_get_uint64(recv_msg, kHelperReplyStatus);
99 errorcode = xpc_dictionary_get_int64(recv_msg, kHelperErrCode);
100
101 switch (reply_status)
102 {
103 case kHelperReply_ACK:
104 mDNSHELPER_DEBUG("NoError: successful reply");
105 break;
106 default:
107 LogMsg("default: Unexpected reply from Helper");
108 break;
109 }
110 }
111 else
112 {
113 LogMsg("SendDict_ToServer Received unexpected reply from daemon [%s]",
114 xpc_dictionary_get_string(recv_msg, XPC_ERROR_KEY_DESCRIPTION));
115 HelperLog("SendDict_ToServer Unexpected Reply contents", recv_msg);
116 }
117
118 dispatch_semaphore_signal(sem);
119 dispatch_release(sem);
120
121 });
122
123 if (dispatch_semaphore_wait(sem, dispatch_time(DISPATCH_TIME_NOW, (maxwait_secs * NSEC_PER_SEC))) != 0)
124 LogMsg("SendDict_ToServer: UNEXPECTED WAIT_TIME in dispatch_semaphore_wait");
125
126 dispatch_release(sem);
127
128 mDNSHELPER_DEBUG("SendDict_ToServer returning with errorcode[%d]", errorcode);
129
130 return errorcode;
131 }
132
133 mDNSlocal xpc_object_t SendDict_GetReply(xpc_object_t msg)
134 {
135 // Create empty dictionary
136 __block xpc_object_t dict = xpc_dictionary_create(NULL, NULL, 0);
137 if (!dict) return NULL;
138 xpc_retain(dict);
139
140 HelperLog("SendDict_GetReply Sending msg to Daemon", msg);
141
142 dispatch_semaphore_t sem = dispatch_semaphore_create(0);
143 dispatch_retain(sem); // for the block below
144
145 xpc_connection_send_message_with_reply(helper_xpc_conn, msg, HelperQueue, ^(xpc_object_t recv_msg)
146 {
147 xpc_type_t type = xpc_get_type(recv_msg);
148
149 if (type == XPC_TYPE_DICTIONARY)
150 {
151 HelperLog("SendDict_GetReply Received reply msg from Daemon", recv_msg);
152 uint64_t reply_status = xpc_dictionary_get_uint64(recv_msg, kHelperReplyStatus);
153
154 switch (reply_status)
155 {
156 case kHelperReply_ACK:
157 mDNSHELPER_DEBUG("NoError: successful reply");
158 break;
159 default:
160 LogMsg("default: Unexpected reply from Helper");
161 break;
162 }
163 // Copy result into dict reply
164 xpc_dictionary_apply(recv_msg, ^bool(const char *key, xpc_object_t value)
165 {
166 xpc_dictionary_set_value(dict, key, value);
167 return true;
168 });
169 }
170 else
171 {
172 LogMsg("SendDict_GetReply Received unexpected reply from daemon [%s]",
173 xpc_dictionary_get_string(recv_msg, XPC_ERROR_KEY_DESCRIPTION));
174 HelperLog("SendDict_GetReply Unexpected Reply contents", recv_msg);
175 }
176
177 dispatch_semaphore_signal(sem);
178 dispatch_release(sem);
179 xpc_release(dict);
180
181 });
182
183 if (dispatch_semaphore_wait(sem, dispatch_time(DISPATCH_TIME_NOW, (maxwait_secs * NSEC_PER_SEC))) != 0)
184 {
185 LogMsg("SendDict_GetReply: UNEXPECTED WAIT_TIME in dispatch_semaphore_wait");
186 xpc_release(dict);
187 dispatch_release(sem);
188
189 return NULL;
190 }
191
192 dispatch_release(sem);
193
194 return dict;
195 }
196
197 //**************************************************************************************************************
198
199 mDNSexport mStatus mDNSHelperInit()
200 {
201 HelperQueue = dispatch_queue_create("com.apple.mDNSResponder.HelperQueue", NULL);
202 if (HelperQueue == NULL)
203 {
204 LogMsg("dispatch_queue_create: Helper queue NULL");
205 return mStatus_NoMemoryErr;
206 }
207 return mStatus_NoError;
208 }
209
210 void mDNSPreferencesSetName(int key, domainlabel *old, domainlabel *new)
211 {
212 struct
213 {
214 char oldname[MAX_DOMAIN_LABEL+1];
215 char newname[MAX_DOMAIN_LABEL+1];
216 } names;
217
218 mDNSPlatformMemZero(names.oldname, MAX_DOMAIN_LABEL + 1);
219 mDNSPlatformMemZero(names.newname, MAX_DOMAIN_LABEL + 1);
220
221 ConvertDomainLabelToCString_unescaped(old, names.oldname);
222
223 if (new)
224 ConvertDomainLabelToCString_unescaped(new, names.newname);
225
226
227 mDNSHELPER_DEBUG("mDNSPreferencesSetName: XPC IPC Test oldname %s newname %s", names.oldname, names.newname);
228 Init_Connection(kHelperService);
229
230 // Create Dictionary To Send
231 xpc_object_t dict = xpc_dictionary_create(NULL, NULL, 0);
232 xpc_dictionary_set_uint64(dict, kHelperMode, set_name);
233
234 xpc_dictionary_set_uint64(dict, kPrefsNameKey, key);
235 xpc_dictionary_set_string(dict, kPrefsOldName, names.oldname);
236 xpc_dictionary_set_string(dict, kPrefsNewName, names.newname);
237
238 SendDict_ToServer(dict);
239 xpc_release(dict);
240 dict = NULL;
241
242 }
243
244 void mDNSRequestBPF()
245 {
246 mDNSHELPER_DEBUG("mDNSRequestBPF: Using XPC IPC");
247 Init_Connection(kHelperService);
248
249 // Create Dictionary To Send
250 xpc_object_t dict = xpc_dictionary_create(NULL, NULL, 0);
251 xpc_dictionary_set_uint64(dict, kHelperMode, bpf_request);
252 SendDict_ToServer(dict);
253 xpc_release(dict);
254 dict = NULL;
255
256 }
257
258 int mDNSPowerRequest(int key, int interval)
259 {
260 int err_code = kHelperErr_NotConnected;
261
262 mDNSHELPER_DEBUG("mDNSPowerRequest: Using XPC IPC calling out to Helper key is [%d] interval is [%d]", key, interval);
263 Init_Connection(kHelperService);
264
265 // Create Dictionary To Send
266 xpc_object_t dict = xpc_dictionary_create(NULL, NULL, 0);
267 xpc_dictionary_set_uint64(dict, kHelperMode, power_req);
268 xpc_dictionary_set_uint64(dict, "powerreq_key", key);
269 xpc_dictionary_set_uint64(dict, "powerreq_interval", interval);
270
271 err_code = SendDict_ToServer(dict);
272 xpc_release(dict);
273 dict = NULL;
274
275 mDNSHELPER_DEBUG("mDNSPowerRequest: Using XPC IPC returning error_code %d", err_code);
276 return err_code;
277 }
278
279 int mDNSSetLocalAddressCacheEntry(int ifindex, int family, const v6addr_t ip, const ethaddr_t eth)
280 {
281 int err_code = kHelperErr_NotConnected;
282
283 mDNSHELPER_DEBUG("mDNSSetLocalAddressCacheEntry: Using XPC IPC calling out to Helper: ifindex is [%d] family is [%d]", ifindex, family);
284
285 Init_Connection(kHelperService);
286
287 // Create Dictionary To Send
288 xpc_object_t dict = xpc_dictionary_create(NULL, NULL, 0);
289 xpc_dictionary_set_uint64(dict, kHelperMode, set_localaddr_cacheentry);
290
291 xpc_dictionary_set_uint64(dict, "slace_ifindex", ifindex);
292 xpc_dictionary_set_uint64(dict, "slace_family", family);
293
294 xpc_dictionary_set_data(dict, "slace_ip", (uint8_t*)ip, sizeof(v6addr_t));
295 xpc_dictionary_set_data(dict, "slace_eth", (uint8_t*)eth, sizeof(ethaddr_t));
296
297 err_code = SendDict_ToServer(dict);
298 xpc_release(dict);
299 dict = NULL;
300
301 mDNSHELPER_DEBUG("mDNSSetLocalAddressCacheEntry: Using XPC IPC returning error_code %d", err_code);
302 return err_code;
303 }
304
305
306 void mDNSNotify(const char *title, const char *msg) // Both strings are UTF-8 text
307 {
308 mDNSHELPER_DEBUG("mDNSNotify() calling out to Helper XPC IPC title[%s] msg[%s]", title, msg);
309
310 Init_Connection(kHelperService);
311
312 // Create Dictionary To Send
313 xpc_object_t dict = xpc_dictionary_create(NULL, NULL, 0);
314 xpc_dictionary_set_uint64(dict, kHelperMode, user_notify);
315
316 xpc_dictionary_set_string(dict, "notify_title", title);
317 xpc_dictionary_set_string(dict, "notify_msg", msg);
318
319 SendDict_ToServer(dict);
320 xpc_release(dict);
321 dict = NULL;
322
323 }
324
325
326 int mDNSKeychainGetSecrets(CFArrayRef *result)
327 {
328
329 CFPropertyListRef plist = NULL;
330 CFDataRef bytes = NULL;
331 unsigned int numsecrets = 0;
332 unsigned int secretsCnt = 0;
333 int error_code = kHelperErr_NotConnected;
334 xpc_object_t reply_dict = NULL;
335 const void *sec = NULL;
336 size_t secrets_size = 0;
337
338 mDNSHELPER_DEBUG("mDNSKeychainGetSecrets: Using XPC IPC calling out to Helper");
339
340 Init_Connection(kHelperService);
341
342 // Create Dictionary To Send
343 xpc_object_t dict = xpc_dictionary_create(NULL, NULL, 0);
344 xpc_dictionary_set_uint64(dict, kHelperMode, keychain_getsecrets);
345
346 reply_dict = SendDict_GetReply(dict);
347
348 if (reply_dict != NULL)
349 {
350 numsecrets = xpc_dictionary_get_uint64(reply_dict, "keychain_num_secrets");
351 sec = xpc_dictionary_get_data(reply_dict, "keychain_secrets", &secrets_size);
352 secretsCnt = xpc_dictionary_get_uint64(reply_dict, "keychain_secrets_count");
353 error_code = xpc_dictionary_get_int64(reply_dict, kHelperErrCode);
354 }
355
356 mDNSHELPER_DEBUG("mDNSKeychainGetSecrets: Using XPC IPC calling out to Helper: numsecrets is %d, secretsCnt is %d error_code is %d secret_size is %d",
357 numsecrets, secretsCnt, error_code, secrets_size);
358
359 if (NULL == (bytes = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, (void*)sec, secretsCnt, kCFAllocatorNull)))
360 {
361 error_code = kHelperErr_ApiErr;
362 LogMsg("mDNSKeychainGetSecrets: CFDataCreateWithBytesNoCopy failed");
363 goto fin;
364 }
365
366 if (NULL == (plist = CFPropertyListCreateWithData(kCFAllocatorDefault, bytes, kCFPropertyListImmutable, NULL, NULL)))
367 {
368 error_code = kHelperErr_ApiErr;
369 LogMsg("mDNSKeychainGetSecrets: CFPropertyListCreateFromXMLData failed");
370 goto fin;
371 }
372
373 if (CFArrayGetTypeID() != CFGetTypeID(plist))
374 {
375 error_code = kHelperErr_ApiErr;
376 LogMsg("mDNSKeychainGetSecrets: Unexpected result type");
377 CFRelease(plist);
378 plist = NULL;
379 goto fin;
380 }
381
382 *result = (CFArrayRef)plist;
383
384
385 fin:
386 if (bytes)
387 CFRelease(bytes);
388 if (dict)
389 xpc_release(dict);
390 if (reply_dict)
391 xpc_release(reply_dict);
392
393 dict = NULL;
394 reply_dict = NULL;
395
396 return error_code;
397 }
398
399
400 int mDNSAutoTunnelSetKeys(int replacedelete, v6addr_t local_inner,
401 v6addr_t local_outer, short local_port, v6addr_t remote_inner,
402 v6addr_t remote_outer, short remote_port, const char* const prefix, const domainname *const fqdn)
403 {
404
405 int err_code = kHelperErr_NotConnected;
406
407 mDNSHELPER_DEBUG("mDNSAutoTunnelSetKeys: Using XPC IPC calling out to Helper. Parameters are repdel[%d], lport[%d], rport[%d], prefix[%s], fqdn[%##s]",
408 replacedelete, local_port, remote_port, prefix, fqdn->c);
409
410
411 char buf1[INET6_ADDRSTRLEN];
412 char buf2[INET6_ADDRSTRLEN];
413 char buf3[INET6_ADDRSTRLEN];
414 char buf4[INET6_ADDRSTRLEN];
415
416 buf1[0] = 0;
417 buf2[0] = 0;
418 buf3[0] = 0;
419 buf4[0] = 0;
420
421 inet_ntop(AF_INET6, local_inner, buf1, sizeof(buf1));
422 inet_ntop(AF_INET6, local_outer, buf2, sizeof(buf2));
423 inet_ntop(AF_INET6, remote_inner, buf3, sizeof(buf3));
424 inet_ntop(AF_INET6, remote_outer, buf4, sizeof(buf4));
425
426 char fqdnStr[MAX_ESCAPED_DOMAIN_NAME + 10] = { 0 }; // Assume the prefix is no larger than 10 chars
427 if (fqdn)
428 {
429 mDNSPlatformStrCopy(fqdnStr, prefix);
430 ConvertDomainNameToCString(fqdn, fqdnStr + mDNSPlatformStrLen(prefix));
431 }
432
433 mDNSHELPER_DEBUG("mDNSAutoTunnelSetKeys: Using XPC IPC calling out to Helper: Parameters are local_inner is %s, local_outeris %s, remote_inner is %s, remote_outer is %s",
434 buf1, buf2, buf3, buf4);
435
436 Init_Connection(kHelperService);
437
438 // Create Dictionary To Send
439 xpc_object_t dict = xpc_dictionary_create(NULL, NULL, 0);
440 xpc_dictionary_set_uint64(dict, kHelperMode, autotunnel_setkeys);
441
442 xpc_dictionary_set_data(dict, "autotunnelsetkeys_localinner", (uint8_t*)local_inner, sizeof(v6addr_t));
443 xpc_dictionary_set_data(dict, "autotunnelsetkeys_localouter", (uint8_t*)local_outer, sizeof(v6addr_t));
444 xpc_dictionary_set_data(dict, "autotunnelsetkeys_remoteinner", (uint8_t*)remote_inner, sizeof(v6addr_t));
445 xpc_dictionary_set_data(dict, "autotunnelsetkeys_remoteouter", (uint8_t*)remote_outer, sizeof(v6addr_t));
446
447 xpc_dictionary_set_uint64(dict, "autotunnelsetkeys_lport", local_port);
448 xpc_dictionary_set_uint64(dict, "autotunnelsetkeys_rport", remote_port);
449 xpc_dictionary_set_uint64(dict, "autotunnelsetkeys_repdel", replacedelete);
450
451 // xpc_dictionary_set_string(dict, "autotunnelsetkeys_prefix", prefix);
452 xpc_dictionary_set_string(dict, "autotunnelsetkeys_fqdnStr", fqdnStr);
453
454 err_code = SendDict_ToServer(dict);
455
456 xpc_release(dict);
457 dict = NULL;
458
459 mDNSHELPER_DEBUG("mDNSAutoTunnelSetKeys: Using XPC IPC returning error_code %d", err_code);
460
461 mDNSHELPER_DEBUG("mDNSAutoTunnelSetKeys: this should NOT be done in mDNSResponder/Helper. For future we shall be using <rdar://problem/13792729>");
462 return err_code;
463 }
464
465 void mDNSSendWakeupPacket(unsigned int ifid, char *eth_addr, char *ip_addr, int iteration)
466 {
467 // (void) ip_addr; // unused
468 // (void) iteration; // unused
469
470 mDNSHELPER_DEBUG("mDNSSendWakeupPacket: Entered ethernet address[%s],ip_address[%s], interface_id[%d], iteration[%d]",
471 eth_addr, ip_addr, ifid, iteration);
472
473 Init_Connection(kHelperService);
474
475 // Create Dictionary To Send
476 xpc_object_t dict = xpc_dictionary_create(NULL, NULL, 0);
477 xpc_dictionary_set_uint64(dict, kHelperMode, send_wakepkt);
478
479 xpc_dictionary_set_uint64(dict, "interface_index", ifid);
480 xpc_dictionary_set_string(dict, "ethernet_address", eth_addr);
481 xpc_dictionary_set_string(dict, "ip_address", ip_addr);
482 xpc_dictionary_set_uint64(dict, "swp_iteration", iteration);
483
484 SendDict_ToServer(dict);
485 xpc_release(dict);
486 dict = NULL;
487
488 }
489
490 void mDNSPacketFilterControl(uint32_t command, char * ifname, uint32_t count, pfArray_t portArray, pfArray_t protocolArray)
491 {
492 struct
493 {
494 pfArray_t portArray;
495 pfArray_t protocolArray;
496 } pfa;
497
498 mDNSPlatformMemCopy(pfa.portArray, portArray, sizeof(pfArray_t));
499 mDNSPlatformMemCopy(pfa.protocolArray, protocolArray, sizeof(pfArray_t));
500
501 mDNSHELPER_DEBUG("mDNSPacketFilterControl: XPC IPC, ifname %s", ifname);
502 Init_Connection(kHelperService);
503
504 // Create Dictionary To Send
505 xpc_object_t dict = xpc_dictionary_create(NULL, NULL, 0);
506 xpc_dictionary_set_uint64(dict, kHelperMode, p2p_packetfilter);
507
508 xpc_dictionary_set_uint64(dict, "pf_opcode", command);
509 if (ifname)
510 xpc_dictionary_set_string(dict, "pf_ifname", ifname);
511 xpc_dictionary_set_uint64(dict, "pf_count", count);
512
513 xpc_dictionary_set_uint64(dict, "pf_port0", pfa.portArray[0]);
514 xpc_dictionary_set_uint64(dict, "pf_port1", pfa.portArray[1]);
515 xpc_dictionary_set_uint64(dict, "pf_port2", pfa.portArray[2]);
516 xpc_dictionary_set_uint64(dict, "pf_port3", pfa.portArray[3]);
517
518 xpc_dictionary_set_uint64(dict, "pf_protocol0", pfa.protocolArray[0]);
519 xpc_dictionary_set_uint64(dict, "pf_protocol1", pfa.protocolArray[1]);
520 xpc_dictionary_set_uint64(dict, "pf_protocol2", pfa.protocolArray[2]);
521 xpc_dictionary_set_uint64(dict, "pf_protocol3", pfa.protocolArray[3]);
522 SendDict_ToServer(dict);
523 xpc_release(dict);
524 dict = NULL;
525
526 mDNSHELPER_DEBUG("mDNSPacketFilterControl: portArray0[%d] portArray1[%d] portArray2[%d] portArray3[%d] protocolArray0[%d] protocolArray1[%d] protocolArray2[%d] protocolArray3[%d]",
527 pfa.portArray[0], pfa.portArray[1], pfa.portArray[2], pfa.portArray[3], pfa.protocolArray[0], pfa.protocolArray[1], pfa.protocolArray[2], pfa.protocolArray[3]);
528
529 }
530
531 void mDNSSendKeepalive(const v6addr_t sadd, const v6addr_t dadd, uint16_t lport, uint16_t rport, uint32_t seq, uint32_t ack, uint16_t win)
532 {
533
534 mDNSHELPER_DEBUG("mDNSSendKeepalive: Using XPC IPC calling out to Helper: lport is[%d] rport is[%d] seq is[%d] ack is[%d] win is[%d]",
535 lport, rport, seq, ack, win);
536
537 char buf1[INET6_ADDRSTRLEN];
538 char buf2[INET6_ADDRSTRLEN];
539
540 buf1[0] = 0;
541 buf2[0] = 0;
542
543 inet_ntop(AF_INET6, sadd, buf1, sizeof(buf1));
544 inet_ntop(AF_INET6, dadd, buf2, sizeof(buf2));
545 mDNSHELPER_DEBUG("mDNSSendKeepalive: Using XPC IPC calling out to Helper: sadd is %s, dadd is %s", buf1, buf2);
546
547 Init_Connection(kHelperService);
548
549 // Create Dictionary To Send
550 xpc_object_t dict = xpc_dictionary_create(NULL, NULL, 0);
551 xpc_dictionary_set_uint64(dict, kHelperMode, send_keepalive);
552
553 xpc_dictionary_set_data(dict, "send_keepalive_sadd", (uint8_t*)sadd, sizeof(v6addr_t));
554 xpc_dictionary_set_data(dict, "send_keepalive_dadd", (uint8_t*)dadd, sizeof(v6addr_t));
555
556 xpc_dictionary_set_uint64(dict, "send_keepalive_lport", lport);
557 xpc_dictionary_set_uint64(dict, "send_keepalive_rport", rport);
558 xpc_dictionary_set_uint64(dict, "send_keepalive_seq", seq);
559 xpc_dictionary_set_uint64(dict, "send_keepalive_ack", ack);
560 xpc_dictionary_set_uint64(dict, "send_keepalive_win", win);
561
562 SendDict_ToServer(dict);
563 xpc_release(dict);
564 dict = NULL;
565
566 }
567
568 int mDNSRetrieveTCPInfo(int family, v6addr_t laddr, uint16_t lport, v6addr_t raddr, uint16_t rport, uint32_t *seq, uint32_t *ack, uint16_t *win, int32_t *intfid)
569 {
570 int error_code = kHelperErr_NotConnected;
571 xpc_object_t reply_dict = NULL;
572
573 mDNSHELPER_DEBUG("mDNSRetrieveTCPInfo: Using XPC IPC calling out to Helper: lport is[%d] rport is[%d] family is[%d]",
574 lport, rport, family);
575
576 char buf1[INET6_ADDRSTRLEN];
577 char buf2[INET6_ADDRSTRLEN];
578 buf1[0] = 0;
579 buf2[0] = 0;
580
581 inet_ntop(AF_INET6, laddr, buf1, sizeof(buf1));
582 inet_ntop(AF_INET6, raddr, buf2, sizeof(buf2));
583 mDNSHELPER_DEBUG("mDNSRetrieveTCPInfo:: Using XPC IPC calling out to Helper: laddr is %s, raddr is %s", buf1, buf2);
584
585 Init_Connection(kHelperService);
586
587 // Create Dictionary To Send
588 xpc_object_t dict = xpc_dictionary_create(NULL, NULL, 0);
589 xpc_dictionary_set_uint64(dict, kHelperMode, retreive_tcpinfo);
590
591 xpc_dictionary_set_data(dict, "retreive_tcpinfo_laddr", (uint8_t*)laddr, sizeof(v6addr_t));
592 xpc_dictionary_set_data(dict, "retreive_tcpinfo_raddr", (uint8_t*)raddr, sizeof(v6addr_t));
593
594 xpc_dictionary_set_uint64(dict, "retreive_tcpinfo_family", family);
595 xpc_dictionary_set_uint64(dict, "retreive_tcpinfo_lport", lport);
596 xpc_dictionary_set_uint64(dict, "retreive_tcpinfo_rport", rport);
597
598 reply_dict = SendDict_GetReply(dict);
599
600 if (reply_dict != NULL)
601 {
602 *seq = xpc_dictionary_get_uint64(reply_dict, "retreive_tcpinfo_seq");
603 *ack = xpc_dictionary_get_uint64(reply_dict, "retreive_tcpinfo_ack");
604 *win = xpc_dictionary_get_uint64(reply_dict, "retreive_tcpinfo_win");
605 *intfid = (int32_t)xpc_dictionary_get_uint64(reply_dict, "retreive_tcpinfo_ifid");
606 error_code = xpc_dictionary_get_int64(reply_dict, kHelperErrCode);
607 }
608
609 mDNSHELPER_DEBUG("mDNSRetrieveTCPInfo: Using XPC IPC calling out to Helper: seq is %d, ack is %d, win is %d, intfid is %d, error is %d",
610 *seq, *ack, *win, *intfid, error_code);
611
612 if (dict)
613 xpc_release(dict);
614 if (reply_dict)
615 xpc_release(reply_dict);
616 dict = NULL;
617 reply_dict = NULL;
618
619 return error_code;
620 }