2 * Copyright (c) 2019-2020 Apple Inc. All rights reserved.
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
8 * https://www.apache.org/licenses/LICENSE-2.0
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.
17 #include "mdns_helpers.h"
19 #include <CoreUtils/CoreUtils.h>
20 #include "DNSMessage.h"
22 //======================================================================================================================
25 MDNS_LOG_CATEGORY_DEFINE(helpers
, "helpers");
27 //======================================================================================================================
30 mdns_snprintf_add(char **ptr
, const char *lim
, const char *fmt
, ...)
33 char * const dst
= ptr
? *ptr
: NULL
;
34 const size_t len
= (size_t)(lim
- dst
);
36 const int n
= vsnprintf(dst
, len
, fmt
, args
);
38 require_quiet(n
>= 0, exit
);
41 if (((size_t)n
) > len
) {
52 //======================================================================================================================
55 mdns_replace_string(char **string_ptr
, const char *replacement
)
60 new_string
= strdup(replacement
);
61 require_action_quiet(new_string
, exit
, err
= kNoMemoryErr
);
65 FreeNullSafe(*string_ptr
);
66 *string_ptr
= new_string
;
73 //======================================================================================================================
76 mdns_make_socket_nonblocking(int sock
)
78 int flags
= fcntl(sock
, F_GETFL
, 0);
80 OSStatus err
= fcntl(sock
, F_SETFL
, flags
);
81 err
= map_global_value_errno(err
!= -1, err
);
85 //======================================================================================================================
88 mdns_mach_ticks_per_second(void)
90 static dispatch_once_t s_once
= 0;
91 static uint64_t s_ticks_per_second
= 0;
92 dispatch_once(&s_once
,
94 mach_timebase_info_data_t info
;
95 const kern_return_t err
= mach_timebase_info(&info
);
96 if (!err
&& (info
.numer
!= 0) && (info
.denom
!= 0)) {
97 s_ticks_per_second
= (info
.denom
* UINT64_C_safe(kNanosecondsPerSecond
)) / info
.numer
;
99 os_log_error(_mdns_helpers_log(),
100 "Unexpected results from mach_timebase_info: err %d numer %u denom %u", err
, info
.numer
, info
.denom
);
101 s_ticks_per_second
= kNanosecondsPerSecond
;
104 return s_ticks_per_second
;
107 //======================================================================================================================
110 mdns_print_obfuscated_ip_address(char * const buf_ptr
, const size_t buf_len
, const struct sockaddr
* const sa
)
114 switch (sa
->sa_family
) {
116 const struct sockaddr_in
* const sin
= (const struct sockaddr_in
*)sa
;
117 n
= DNSMessagePrintObfuscatedIPv4Address(strbuf
, sizeof(strbuf
), ntohl(sin
->sin_addr
.s_addr
));
118 require_return_value(n
>= 0, n
);
119 return snprintf(buf_ptr
, buf_len
, "<IPv4:%s>", strbuf
);
122 const struct sockaddr_in6
* const sin6
= (const struct sockaddr_in6
*)sa
;
123 n
= DNSMessagePrintObfuscatedIPv6Address(strbuf
, sizeof(strbuf
), sin6
->sin6_addr
.s6_addr
);
124 require_return_value(n
>= 0, n
);
125 return snprintf(buf_ptr
, buf_len
, "<IPv6:%s>", strbuf
);