]> git.saurik.com Git - apple/mdnsresponder.git/blob - mDNSMacOSX/dnssd_xpc.c
mDNSResponder-1310.80.1.tar.gz
[apple/mdnsresponder.git] / mDNSMacOSX / dnssd_xpc.c
1 /*
2 * Copyright (c) 2019-2020 Apple Inc. All rights reserved.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * https://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include "dnssd_xpc.h"
18
19 //======================================================================================================================
20 // MARK: - XPC Dictionary Helper Declarations
21
22 static int32_t
23 _dnssd_xpc_dictionary_get_int32(xpc_object_t dict, const char *key, bool *out_valid);
24
25 static int64_t
26 _dnssd_xpc_dictionary_get_int64(xpc_object_t dict, const char *key, bool *out_valid);
27
28 static int64_t
29 _dnssd_xpc_dictionary_get_int64_limited(xpc_object_t dict, const char *key, int64_t min, int64_t max, bool *out_valid);
30
31 static uint16_t
32 _dnssd_xpc_dictionary_get_uint16(xpc_object_t dict, const char *key, bool *out_valid);
33
34 static uint32_t
35 _dnssd_xpc_dictionary_get_uint32(xpc_object_t dict, const char *key, bool *out_valid);
36
37 static uint64_t
38 _dnssd_xpc_dictionary_get_uint64(xpc_object_t dict, const char *key, bool *out_valid);
39
40 static uint64_t
41 _dnssd_xpc_dictionary_get_uint64_limited(xpc_object_t dict, const char *key, uint64_t min, uint64_t max,
42 bool *out_valid);
43
44 static xpc_object_t
45 _dnssd_xpc_dictionary_get_value(xpc_object_t dict, const char *key, xpc_type_t type);
46
47 //======================================================================================================================
48 // MARK: - Top-Level Message Dictionaries
49
50 #define DNSSD_XPC_MESSAGE_KEY_COMMAND "command"
51 #define DNSSD_XPC_MESSAGE_KEY_ERROR "error"
52 #define DNSSD_XPC_MESSAGE_KEY_ID "id"
53 #define DNSSD_XPC_MESSAGE_KEY_PARAMS "params"
54 #define DNSSD_XPC_MESSAGE_KEY_RESULTS "results"
55
56 //======================================================================================================================
57
58 const char * _Nullable
59 dnssd_xpc_message_get_command(xpc_object_t msg)
60 {
61 return xpc_dictionary_get_string(msg, DNSSD_XPC_MESSAGE_KEY_COMMAND);
62 }
63
64 //======================================================================================================================
65
66 void
67 dnssd_xpc_message_set_command(xpc_object_t msg, const char *command)
68 {
69 xpc_dictionary_set_string(msg, DNSSD_XPC_MESSAGE_KEY_COMMAND, command);
70 }
71
72 //======================================================================================================================
73
74 DNSServiceErrorType
75 dnssd_xpc_message_get_error(xpc_object_t msg, bool *out_valid)
76 {
77 return _dnssd_xpc_dictionary_get_int32(msg, DNSSD_XPC_MESSAGE_KEY_ERROR, out_valid);
78 }
79
80 //======================================================================================================================
81
82 void
83 dnssd_xpc_message_set_error(xpc_object_t msg, DNSServiceErrorType error)
84 {
85 xpc_dictionary_set_int64(msg, DNSSD_XPC_MESSAGE_KEY_ERROR, error);
86 }
87
88 //======================================================================================================================
89
90 uint64_t
91 dnssd_xpc_message_get_id(xpc_object_t msg, bool *out_valid)
92 {
93 return _dnssd_xpc_dictionary_get_uint64(msg, DNSSD_XPC_MESSAGE_KEY_ID, out_valid);
94 }
95
96 //======================================================================================================================
97
98 void
99 dnssd_xpc_message_set_id(xpc_object_t msg, uint64_t ident)
100 {
101 xpc_dictionary_set_uint64(msg, DNSSD_XPC_MESSAGE_KEY_ID, ident);
102 }
103
104 //======================================================================================================================
105
106 xpc_object_t
107 dnssd_xpc_message_get_parameters(xpc_object_t msg)
108 {
109 return xpc_dictionary_get_dictionary(msg, DNSSD_XPC_MESSAGE_KEY_PARAMS);
110 }
111
112 //======================================================================================================================
113
114 void
115 dnssd_xpc_message_set_parameters(xpc_object_t msg, xpc_object_t params)
116 {
117 xpc_dictionary_set_value(msg, DNSSD_XPC_MESSAGE_KEY_PARAMS, params);
118 }
119
120 //======================================================================================================================
121
122 xpc_object_t
123 dnssd_xpc_message_get_results(xpc_object_t msg)
124 {
125 return xpc_dictionary_get_array(msg, DNSSD_XPC_MESSAGE_KEY_RESULTS);
126 }
127
128 //======================================================================================================================
129
130 void
131 dnssd_xpc_message_set_results(xpc_object_t msg, xpc_object_t results)
132 {
133 xpc_dictionary_set_value(msg, DNSSD_XPC_MESSAGE_KEY_RESULTS, results);
134 }
135
136 //======================================================================================================================
137 // MARK: - Parameter Dictionaries
138
139 #define DNSSD_XPC_PARAMETERS_KEY_DELEGATE_ID "delegate_id"
140 #define DNSSD_XPC_PARAMETERS_KEY_FLAGS "flags"
141 #define DNSSD_XPC_PARAMETERS_KEY_ACCOUNT_ID "account_id"
142 #define DNSSD_XPC_PARAMETERS_KEY_HOSTNAME "hostname"
143 #define DNSSD_XPC_PARAMETERS_KEY_INTERFACE_INDEX "interface_index"
144 #define DNSSD_XPC_PARAMETERS_KEY_NEED_AUTH_TAGS "need_auth_tags"
145 #define DNSSD_XPC_PARAMETERS_KEY_PROTOCOLS "protocols"
146 #define DNSSD_XPC_PARAMETERS_KEY_NEED_ENCRYPTION "need_encryption"
147 #define DNSSD_XPC_PARAMETERS_KEY_FALLBACK_CONFIG "fallback_config"
148 #define DNSSD_XPC_PARAMETERS_KEY_RESOLVER_UUIDS "resolver_uuids"
149 #define DNSSD_XPC_PARAMETERS_KEY_SERVICE_SCHEME "service_scheme"
150
151 //======================================================================================================================
152
153 pid_t
154 dnssd_xpc_parameters_get_delegate_pid(xpc_object_t params, bool *out_valid)
155 {
156 return (pid_t)_dnssd_xpc_dictionary_get_int64(params, DNSSD_XPC_PARAMETERS_KEY_DELEGATE_ID, out_valid);
157 }
158
159 //======================================================================================================================
160
161 void
162 dnssd_xpc_parameters_set_delegate_pid(xpc_object_t params, pid_t pid)
163 {
164 xpc_dictionary_set_int64(params, DNSSD_XPC_PARAMETERS_KEY_DELEGATE_ID, pid);
165 }
166
167 //======================================================================================================================
168
169 const uint8_t *
170 dnssd_xpc_parameters_get_delegate_uuid(xpc_object_t params)
171 {
172 return xpc_dictionary_get_uuid(params, DNSSD_XPC_PARAMETERS_KEY_DELEGATE_ID);
173 }
174
175 //======================================================================================================================
176
177 void
178 dnssd_xpc_parameters_set_delegate_uuid(xpc_object_t params, uuid_t uuid)
179 {
180 xpc_dictionary_set_uuid(params, DNSSD_XPC_PARAMETERS_KEY_DELEGATE_ID, uuid);
181 }
182
183 //======================================================================================================================
184
185 audit_token_t * _Nullable
186 dnssd_xpc_parameters_get_delegate_audit_token(const xpc_object_t params, audit_token_t * const audit_token_storage)
187 {
188 size_t size;
189 const void * const data = xpc_dictionary_get_data(params, DNSSD_XPC_PARAMETERS_KEY_DELEGATE_ID, &size);
190 if (data && (size == sizeof(*audit_token_storage))) {
191 memcpy(audit_token_storage, data, size);
192 return audit_token_storage;
193 } else {
194 return NULL;
195 }
196 }
197
198 //======================================================================================================================
199
200 void
201 dnssd_xpc_parameters_set_delegate_audit_token(const xpc_object_t params, const audit_token_t * const audit_token)
202 {
203 xpc_dictionary_set_data(params, DNSSD_XPC_PARAMETERS_KEY_DELEGATE_ID, audit_token, sizeof(*audit_token));
204 }
205
206 //======================================================================================================================
207
208 DNSServiceFlags
209 dnssd_xpc_parameters_get_flags(xpc_object_t params, bool *out_valid)
210 {
211 return _dnssd_xpc_dictionary_get_uint32(params, DNSSD_XPC_PARAMETERS_KEY_FLAGS, out_valid);
212 }
213
214 //======================================================================================================================
215
216 void
217 dnssd_xpc_parameters_set_flags(xpc_object_t params, DNSServiceFlags flags)
218 {
219 xpc_dictionary_set_uint64(params, DNSSD_XPC_PARAMETERS_KEY_FLAGS, flags);
220 }
221
222 //======================================================================================================================
223
224 const char *
225 dnssd_xpc_parameters_get_account_id(xpc_object_t params)
226 {
227 return xpc_dictionary_get_string(params, DNSSD_XPC_PARAMETERS_KEY_ACCOUNT_ID);
228 }
229
230 //======================================================================================================================
231
232 void
233 dnssd_xpc_parameters_set_account_id(xpc_object_t params, const char *account_id)
234 {
235 xpc_dictionary_set_string(params, DNSSD_XPC_PARAMETERS_KEY_ACCOUNT_ID, account_id);
236 }
237
238 //======================================================================================================================
239
240 xpc_object_t
241 dnssd_xpc_parameters_get_hostname_object(xpc_object_t params)
242 {
243 return _dnssd_xpc_dictionary_get_value(params, DNSSD_XPC_PARAMETERS_KEY_HOSTNAME, XPC_TYPE_STRING);
244 }
245
246 //======================================================================================================================
247
248 void
249 dnssd_xpc_parameters_set_hostname(xpc_object_t params, const char *hostname)
250 {
251 xpc_dictionary_set_string(params, DNSSD_XPC_PARAMETERS_KEY_HOSTNAME, hostname);
252 }
253
254 //======================================================================================================================
255
256 uint32_t
257 dnssd_xpc_parameters_get_interface_index(xpc_object_t params, bool *out_valid)
258 {
259 return _dnssd_xpc_dictionary_get_uint32(params, DNSSD_XPC_PARAMETERS_KEY_INTERFACE_INDEX, out_valid);
260 }
261
262 //======================================================================================================================
263
264 void
265 dnssd_xpc_parameters_set_interface_index(xpc_object_t params, uint32_t interface_index)
266 {
267 xpc_dictionary_set_uint64(params, DNSSD_XPC_PARAMETERS_KEY_INTERFACE_INDEX, interface_index);
268 }
269
270 //======================================================================================================================
271
272 bool
273 dnssd_xpc_parameters_get_need_authentication_tags(xpc_object_t params)
274 {
275 return xpc_dictionary_get_bool(params, DNSSD_XPC_PARAMETERS_KEY_NEED_AUTH_TAGS);
276 }
277
278 //======================================================================================================================
279
280 void
281 dnssd_xpc_parameters_set_need_authentication_tags(xpc_object_t params, bool need_auth_tags)
282 {
283 xpc_dictionary_set_bool(params, DNSSD_XPC_PARAMETERS_KEY_NEED_AUTH_TAGS, need_auth_tags);
284 }
285
286 //======================================================================================================================
287
288 void
289 dnssd_xpc_parameters_set_need_encrypted_query(xpc_object_t params, bool need, _Nullable xpc_object_t fallback_config)
290 {
291 xpc_dictionary_set_bool(params, DNSSD_XPC_PARAMETERS_KEY_NEED_ENCRYPTION, need);
292 if (fallback_config != NULL) {
293 xpc_dictionary_set_value(params, DNSSD_XPC_PARAMETERS_KEY_FALLBACK_CONFIG, fallback_config);
294 }
295 }
296
297 //======================================================================================================================
298
299 bool
300 dnssd_xpc_parameters_get_need_encrypted_query(xpc_object_t params)
301 {
302 return xpc_dictionary_get_bool(params, DNSSD_XPC_PARAMETERS_KEY_NEED_ENCRYPTION);
303 }
304
305 //======================================================================================================================
306
307 xpc_object_t _Nullable
308 dnssd_xpc_parameters_get_fallback_config(xpc_object_t params)
309 {
310 return xpc_dictionary_get_value(params, DNSSD_XPC_PARAMETERS_KEY_FALLBACK_CONFIG);
311 }
312
313 //======================================================================================================================
314
315 xpc_object_t _Nullable
316 dnssd_xpc_parameters_get_resolver_uuid_array(xpc_object_t params)
317 {
318 return xpc_dictionary_get_value(params, DNSSD_XPC_PARAMETERS_KEY_RESOLVER_UUIDS);
319 }
320
321 //======================================================================================================================
322
323 void
324 dnssd_xpc_parameters_add_resolver_uuid(xpc_object_t params, uuid_t _Nonnull uuid)
325 {
326 xpc_object_t resolver_uuid_array = xpc_dictionary_get_value(params, DNSSD_XPC_PARAMETERS_KEY_RESOLVER_UUIDS);
327 if (resolver_uuid_array == NULL) {
328 resolver_uuid_array = xpc_array_create(NULL, 0);
329 xpc_dictionary_set_value(params, DNSSD_XPC_PARAMETERS_KEY_RESOLVER_UUIDS, resolver_uuid_array);
330 xpc_release(resolver_uuid_array);
331 }
332 xpc_array_set_uuid(resolver_uuid_array, XPC_ARRAY_APPEND, uuid);
333 }
334
335 //======================================================================================================================
336
337 DNSServiceProtocol
338 dnssd_xpc_parameters_get_protocols(xpc_object_t params, bool *out_valid)
339 {
340 return _dnssd_xpc_dictionary_get_uint32(params, DNSSD_XPC_PARAMETERS_KEY_PROTOCOLS, out_valid);
341 }
342
343 //======================================================================================================================
344
345 void
346 dnssd_xpc_parameters_set_protocols(xpc_object_t params, DNSServiceProtocol protocols)
347 {
348 xpc_dictionary_set_uint64(params, DNSSD_XPC_PARAMETERS_KEY_PROTOCOLS, protocols);
349 }
350
351 //======================================================================================================================
352
353 const char * _Nullable
354 dnssd_xpc_parameters_get_service_scheme(xpc_object_t params)
355 {
356 return xpc_dictionary_get_string(params, DNSSD_XPC_PARAMETERS_KEY_SERVICE_SCHEME);
357 }
358
359 //======================================================================================================================
360
361 void
362 dnssd_xpc_parameters_set_service_scheme(xpc_object_t params, const char *service_scheme)
363 {
364 xpc_dictionary_set_string(params, DNSSD_XPC_PARAMETERS_KEY_SERVICE_SCHEME, service_scheme);
365 }
366
367 //======================================================================================================================
368 // MARK: - Result Dictionaries
369
370 #define DNSSD_XPC_RESULT_KEY_AUTH_TAG "auth_tag"
371 #define DNSSD_XPC_RESULT_KEY_CNAME_UPDATE "cname_update"
372 #define DNSSD_XPC_RESULT_KEY_ERROR "error"
373 #define DNSSD_XPC_RESULT_KEY_FLAGS "flags"
374 #define DNSSD_XPC_RESULT_KEY_INTERFACE_INDEX "interface_index"
375 #define DNSSD_XPC_RESULT_KEY_PROVIDER_NAME "provider_name"
376 #define DNSSD_XPC_RESULT_KEY_RECORD_CLASS "rclass"
377 #define DNSSD_XPC_RESULT_KEY_RECORD_DATA "rdata"
378 #define DNSSD_XPC_RESULT_KEY_RECORD_NAME "rname"
379 #define DNSSD_XPC_RESULT_KEY_RECORD_PROTOCOL "rprotocol"
380 #define DNSSD_XPC_RESULT_KEY_RECORD_TYPE "rtype"
381
382 //======================================================================================================================
383
384 xpc_object_t
385 dnssd_xpc_result_get_authentication_tag_object(xpc_object_t result)
386 {
387 return _dnssd_xpc_dictionary_get_value(result, DNSSD_XPC_RESULT_KEY_AUTH_TAG, XPC_TYPE_DATA);
388 }
389
390 //======================================================================================================================
391
392 void
393 dnssd_xpc_result_set_authentication_tag(xpc_object_t result, const void *auth_tag_ptr, size_t auth_tag_len)
394 {
395 xpc_dictionary_set_data(result, DNSSD_XPC_RESULT_KEY_AUTH_TAG, auth_tag_ptr, auth_tag_len);
396 }
397
398 //======================================================================================================================
399
400 DNSServiceErrorType
401 dnssd_xpc_result_get_error(xpc_object_t result, bool *out_valid)
402 {
403 return _dnssd_xpc_dictionary_get_int32(result, DNSSD_XPC_RESULT_KEY_ERROR, out_valid);
404 }
405
406 //======================================================================================================================
407
408 void
409 dnssd_xpc_result_set_error(xpc_object_t result, DNSServiceErrorType error)
410 {
411 xpc_dictionary_set_int64(result, DNSSD_XPC_RESULT_KEY_ERROR, error);
412 }
413
414 //======================================================================================================================
415
416 DNSServiceFlags
417 dnssd_xpc_result_get_flags(xpc_object_t result, bool *out_valid)
418 {
419 return _dnssd_xpc_dictionary_get_uint32(result, DNSSD_XPC_RESULT_KEY_FLAGS, out_valid);
420 }
421
422 //======================================================================================================================
423
424 void
425 dnssd_xpc_result_set_flags(xpc_object_t result, DNSServiceFlags flags)
426 {
427 xpc_dictionary_set_uint64(result, DNSSD_XPC_RESULT_KEY_FLAGS, flags);
428 }
429
430 //======================================================================================================================
431
432 uint32_t
433 dnssd_xpc_result_get_interface_index(xpc_object_t result, bool *out_valid)
434 {
435 return _dnssd_xpc_dictionary_get_uint32(result, DNSSD_XPC_RESULT_KEY_INTERFACE_INDEX, out_valid);
436 }
437
438 //======================================================================================================================
439
440 void
441 dnssd_xpc_result_set_interface_index(xpc_object_t result, uint32_t interface_index)
442 {
443 xpc_dictionary_set_uint64(result, DNSSD_XPC_RESULT_KEY_INTERFACE_INDEX, interface_index);
444 }
445
446 //======================================================================================================================
447
448 uint16_t
449 dnssd_xpc_result_get_record_class(xpc_object_t result, bool *out_valid)
450 {
451 return _dnssd_xpc_dictionary_get_uint16(result, DNSSD_XPC_RESULT_KEY_RECORD_CLASS, out_valid);
452 }
453
454 //======================================================================================================================
455
456 void
457 dnssd_xpc_result_set_record_class(xpc_object_t result, uint16_t class)
458 {
459 xpc_dictionary_set_uint64(result, DNSSD_XPC_RESULT_KEY_RECORD_CLASS, class);
460 }
461
462 //======================================================================================================================
463
464 xpc_object_t
465 dnssd_xpc_result_get_record_data_object(xpc_object_t result)
466 {
467 return _dnssd_xpc_dictionary_get_value(result, DNSSD_XPC_RESULT_KEY_RECORD_DATA, XPC_TYPE_DATA);
468 }
469
470 //======================================================================================================================
471
472 void
473 dnssd_xpc_result_set_record_data(xpc_object_t result, const void *data_ptr, size_t data_len)
474 {
475 xpc_dictionary_set_data(result, DNSSD_XPC_RESULT_KEY_RECORD_DATA, data_ptr, data_len);
476 }
477
478 //======================================================================================================================
479
480 xpc_object_t
481 dnssd_xpc_result_get_record_name_object(xpc_object_t result)
482 {
483 return _dnssd_xpc_dictionary_get_value(result, DNSSD_XPC_RESULT_KEY_RECORD_NAME, XPC_TYPE_STRING);
484 }
485
486 //======================================================================================================================
487
488 void
489 dnssd_xpc_result_set_record_name(xpc_object_t result, const char *name)
490 {
491 xpc_dictionary_set_string(result, DNSSD_XPC_RESULT_KEY_RECORD_NAME, name);
492 }
493
494 //======================================================================================================================
495
496 uint16_t
497 dnssd_xpc_result_get_record_type(xpc_object_t result, bool *out_valid)
498 {
499 return _dnssd_xpc_dictionary_get_uint16(result, DNSSD_XPC_RESULT_KEY_RECORD_TYPE, out_valid);
500 }
501
502 //======================================================================================================================
503
504 void
505 dnssd_xpc_result_set_record_type(xpc_object_t result, uint16_t type)
506 {
507 xpc_dictionary_set_uint64(result, DNSSD_XPC_RESULT_KEY_RECORD_TYPE, type);
508 }
509
510 //======================================================================================================================
511
512 uint16_t
513 dnssd_xpc_result_get_record_protocol(xpc_object_t result, bool * out_valid)
514 {
515 return _dnssd_xpc_dictionary_get_uint16(result, DNSSD_XPC_RESULT_KEY_RECORD_PROTOCOL, out_valid);
516 }
517
518 //======================================================================================================================
519
520 void
521 dnssd_xpc_result_set_record_protocol(xpc_object_t result, uint16_t protocol)
522 {
523 xpc_dictionary_set_uint64(result, DNSSD_XPC_RESULT_KEY_RECORD_PROTOCOL, protocol);
524 }
525
526 //======================================================================================================================
527
528 xpc_object_t
529 dnssd_xpc_result_get_provider_name_object(xpc_object_t result)
530 {
531 return _dnssd_xpc_dictionary_get_value(result, DNSSD_XPC_RESULT_KEY_PROVIDER_NAME, XPC_TYPE_STRING);
532 }
533
534 //======================================================================================================================
535
536 void
537 dnssd_xpc_result_set_provider_name(xpc_object_t result, const char *name)
538 {
539 xpc_dictionary_set_string(result, DNSSD_XPC_RESULT_KEY_PROVIDER_NAME, name);
540 }
541
542 //======================================================================================================================
543
544 xpc_object_t
545 dnssd_xpc_result_get_cname_update(xpc_object_t result)
546 {
547 return xpc_dictionary_get_array(result, DNSSD_XPC_RESULT_KEY_CNAME_UPDATE);
548 }
549
550 //======================================================================================================================
551
552 void
553 dnssd_xpc_result_set_cname_update(xpc_object_t result, xpc_object_t cname_update)
554 {
555 xpc_dictionary_set_value(result, DNSSD_XPC_RESULT_KEY_CNAME_UPDATE, cname_update);
556 }
557
558 //======================================================================================================================
559 // MARK: - XPC Dictionary Helpers
560
561 static int32_t
562 _dnssd_xpc_dictionary_get_int32(xpc_object_t dict, const char *key, bool *out_valid)
563 {
564 return (int32_t)_dnssd_xpc_dictionary_get_int64_limited(dict, key, INT32_MIN, INT32_MAX, out_valid);
565 }
566
567 //======================================================================================================================
568
569 static int64_t
570 _dnssd_xpc_dictionary_get_int64(xpc_object_t dict, const char *key, bool *out_valid)
571 {
572 return _dnssd_xpc_dictionary_get_int64_limited(dict, key, INT64_MIN, INT64_MAX, out_valid);
573 }
574
575 //======================================================================================================================
576
577 static int64_t
578 _dnssd_xpc_dictionary_get_int64_limited(xpc_object_t dict, const char *key, int64_t min, int64_t max, bool *out_valid)
579 {
580 int64_t i64;
581 bool valid;
582
583 xpc_object_t const value = _dnssd_xpc_dictionary_get_value(dict, key, XPC_TYPE_INT64);
584 if (value) {
585 i64 = xpc_int64_get_value(value);
586 if ((i64 >= min) && (i64 <= max)) {
587 valid = true;
588 } else {
589 i64 = 0;
590 valid = false;
591 }
592 } else {
593 i64 = 0;
594 valid = false;
595 }
596 if (out_valid) {
597 *out_valid = valid;
598 }
599 return i64;
600 }
601
602 //======================================================================================================================
603
604 static uint16_t
605 _dnssd_xpc_dictionary_get_uint16(xpc_object_t dict, const char *key, bool *out_valid)
606 {
607 return (uint16_t)_dnssd_xpc_dictionary_get_uint64_limited(dict, key, 0, UINT16_MAX, out_valid);
608 }
609
610 //======================================================================================================================
611
612 static uint32_t
613 _dnssd_xpc_dictionary_get_uint32(xpc_object_t dict, const char *key, bool *out_valid)
614 {
615 return (uint32_t)_dnssd_xpc_dictionary_get_uint64_limited(dict, key, 0, UINT32_MAX, out_valid);
616 }
617
618 //======================================================================================================================
619
620 static uint64_t
621 _dnssd_xpc_dictionary_get_uint64(xpc_object_t dict, const char *key, bool *out_valid)
622 {
623 return _dnssd_xpc_dictionary_get_uint64_limited(dict, key, 0, UINT64_MAX, out_valid);
624 }
625
626 //======================================================================================================================
627
628 static uint64_t
629 _dnssd_xpc_dictionary_get_uint64_limited(xpc_object_t dict, const char *key, uint64_t min, uint64_t max,
630 bool *out_valid)
631 {
632 uint64_t u64;
633 bool valid;
634
635 xpc_object_t const value = _dnssd_xpc_dictionary_get_value(dict, key, XPC_TYPE_UINT64);
636 if (value) {
637 u64 = xpc_uint64_get_value(value);
638 if ((u64 >= min) && (u64 <= max)) {
639 valid = true;
640 } else {
641 u64 = 0;
642 valid = false;
643 }
644 } else {
645 u64 = 0;
646 valid = false;
647 }
648 if (out_valid) {
649 *out_valid = valid;
650 }
651 return u64;
652 }
653
654 //======================================================================================================================
655
656 static xpc_object_t
657 _dnssd_xpc_dictionary_get_value(xpc_object_t dict, const char *key, xpc_type_t type)
658 {
659 xpc_object_t value = xpc_dictionary_get_value(dict, key);
660 return (value && (xpc_get_type(value) == type)) ? value : NULL;
661 }