2 * Copyright (c) 2002-2019 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 * http://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.
20 #include "mDNSFeatures.h"
22 #if MDNSRESPONDER_SUPPORTS(APPLE, OS_LOG)
26 // Set MDNS_DEBUGMSGS to 0 to optimize debugf() calls out of the compiled code
27 // Set MDNS_DEBUGMSGS to 1 to generate normal debugging messages
28 // Set MDNS_DEBUGMSGS to 2 to generate verbose debugging messages
29 // MDNS_DEBUGMSGS is normally set in the project options (or makefile) but can also be set here if desired
30 // (If you edit the file here to turn on MDNS_DEBUGMSGS while you're debugging some code, be careful
31 // not to accidentally check-in that change by mistake when you check in your other changes.)
33 //#undef MDNS_DEBUGMSGS
34 //#define MDNS_DEBUGMSGS 2
36 // Set MDNS_CHECK_PRINTF_STYLE_FUNCTIONS to 1 to enable extra GCC compiler warnings
37 // Note: You don't normally want to do this, because it generates a bunch of
38 // spurious warnings for the following custom extensions implemented by mDNS_vsnprintf:
39 // warning: `#' flag used with `%s' printf format (for %#s -- pascal string format)
40 // warning: repeated `#' flag in format (for %##s -- DNS name string format)
41 // warning: double format, pointer arg (arg 2) (for %.4a, %.16a, %#a -- IP address formats)
42 #define MDNS_CHECK_PRINTF_STYLE_FUNCTIONS 0
44 #if MDNSRESPONDER_SUPPORTS(APPLE, OS_LOG)
45 typedef os_log_t mDNSLogCategory_t
;
47 typedef os_log_type_t mDNSLogLevel_t
;
48 #define MDNS_LOG_FAULT OS_LOG_TYPE_FAULT
49 #define MDNS_LOG_ERROR OS_LOG_TYPE_ERROR
50 #define MDNS_LOG_WARNING OS_LOG_TYPE_DEFAULT
51 #define MDNS_LOG_DEFAULT OS_LOG_TYPE_DEFAULT
52 #define MDNS_LOG_INFO OS_LOG_TYPE_DEFAULT
53 #define MDNS_LOG_DEBUG OS_LOG_TYPE_DEBUG
55 typedef const char * mDNSLogCategory_t
;
67 #if MDNSRESPONDER_SUPPORTS(APPLE, OS_LOG)
68 extern os_log_t mDNSLogCategory_Default
;
69 extern os_log_t mDNSLogCategory_mDNS
;
70 extern os_log_t mDNSLogCategory_uDNS
;
71 extern os_log_t mDNSLogCategory_SPS
;
72 extern os_log_t mDNSLogCategory_XPC
;
74 #define MDNS_LOG_CATEGORY_DEFINITION(NAME) mDNSLogCategory_ ## NAME
76 #define MDNS_LOG_CATEGORY_DEFINITION(NAME) # NAME
79 #define MDNS_LOG_CATEGORY_DEFAULT MDNS_LOG_CATEGORY_DEFINITION(Default)
80 #define MDNS_LOG_CATEGORY_MDNS MDNS_LOG_CATEGORY_DEFINITION(mDNS)
81 #define MDNS_LOG_CATEGORY_UDNS MDNS_LOG_CATEGORY_DEFINITION(uDNS)
82 #define MDNS_LOG_CATEGORY_SPS MDNS_LOG_CATEGORY_DEFINITION(SPS)
83 #define MDNS_LOG_CATEGORY_XPC MDNS_LOG_CATEGORY_DEFINITION(XPC)
85 // Set this symbol to 1 to answer remote queries for our Address, and reverse mapping PTR
86 #define ANSWER_REMOTE_HOSTNAME_QUERIES 0
88 // Set this symbol to 1 to do extra debug checks on malloc() and free()
89 // Set this symbol to 2 to write a log message for every malloc() and free()
90 // #define MDNS_MALLOC_DEBUGGING 1
92 #if (MDNS_MALLOC_DEBUGGING > 0) && defined(WIN32)
93 #error "Malloc debugging does not yet work on Windows"
96 //#define ForceAlerts 1
97 //#define LogTimeStamps 1
99 // Developer-settings section ends here
101 #if MDNS_CHECK_PRINTF_STYLE_FUNCTIONS
102 #define IS_A_PRINTF_STYLE_FUNCTION(F,A) __attribute__ ((format(printf,F,A)))
104 #define IS_A_PRINTF_STYLE_FUNCTION(F,A)
111 // Variable argument macro support. Use ANSI C99 __VA_ARGS__ where possible. Otherwise, use the next best thing.
113 #if (defined(__GNUC__))
114 #if ((__GNUC__ > 3) || ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 2)))
115 #define MDNS_C99_VA_ARGS 1
116 #define MDNS_GNU_VA_ARGS 0
118 #define MDNS_C99_VA_ARGS 0
119 #define MDNS_GNU_VA_ARGS 1
121 #define MDNS_HAS_VA_ARG_MACROS 1
122 #elif (_MSC_VER >= 1400) // Visual Studio 2005 and later
123 #define MDNS_C99_VA_ARGS 1
124 #define MDNS_GNU_VA_ARGS 0
125 #define MDNS_HAS_VA_ARG_MACROS 1
126 #elif (defined(__MWERKS__))
127 #define MDNS_C99_VA_ARGS 1
128 #define MDNS_GNU_VA_ARGS 0
129 #define MDNS_HAS_VA_ARG_MACROS 1
131 #define MDNS_C99_VA_ARGS 0
132 #define MDNS_GNU_VA_ARGS 0
133 #define MDNS_HAS_VA_ARG_MACROS 0
136 #if (MDNS_HAS_VA_ARG_MACROS)
137 #if (MDNS_C99_VA_ARGS)
138 #define MDNS_LOG_DEFINITION(LEVEL, ...) \
139 do { if (mDNS_LoggingEnabled) LogMsgWithLevel(MDNS_LOG_CATEGORY_DEFAULT, LEVEL, __VA_ARGS__); } while (0)
141 #define debug_noop(...) do {} while(0)
142 #define LogMsg(...) LogMsgWithLevel(MDNS_LOG_CATEGORY_DEFAULT, MDNS_LOG_DEFAULT, __VA_ARGS__)
143 #define LogOperation(...) MDNS_LOG_DEFINITION(MDNS_LOG_INFO, __VA_ARGS__)
144 #define LogSPS(...) MDNS_LOG_DEFINITION(MDNS_LOG_INFO, __VA_ARGS__)
145 #define LogInfo(...) MDNS_LOG_DEFINITION(MDNS_LOG_INFO, __VA_ARGS__)
146 #define LogDebug(...) MDNS_LOG_DEFINITION(MDNS_LOG_DEBUG, __VA_ARGS__)
147 #elif (MDNS_GNU_VA_ARGS)
148 #define MDNS_LOG_DEFINITION(LEVEL, ARGS...) \
149 do { if (mDNS_LoggingEnabled) LogMsgWithLevel(MDNS_LOG_CATEGORY_DEFAULT, LEVEL, ARGS); } while (0)
151 #define debug_noop(ARGS...) do {} while (0)
152 #define LogMsg(ARGS... ) LogMsgWithLevel(MDNS_LOG_CATEGORY_DEFAULT, MDNS_LOG_DEFAULT, ARGS)
153 #define LogOperation(ARGS...) MDNS_LOG_DEFINITION(MDNS_LOG_INFO, ARGS)
154 #define LogSPS(ARGS...) MDNS_LOG_DEFINITION(MDNS_LOG_INFO, ARGS)
155 #define LogInfo(ARGS...) MDNS_LOG_DEFINITION(MDNS_LOG_INFO, ARGS)
156 #define LogDebug(ARGS...) MDNS_LOG_DEFINITION(MDNS_LOG_DEBUG, ARGS)
158 #error "Unknown variadic macros"
161 // If your platform does not support variadic macros, you need to define the following variadic functions.
162 // See mDNSShared/mDNSDebug.c for sample implementation
163 #define debug_noop 1 ? (void)0 : (void)
164 #define LogMsg LogMsg_
165 #define LogOperation (mDNS_LoggingEnabled == 0) ? ((void)0) : LogOperation_
166 #define LogSPS (mDNS_LoggingEnabled == 0) ? ((void)0) : LogSPS_
167 #define LogInfo (mDNS_LoggingEnabled == 0) ? ((void)0) : LogInfo_
168 #define LogDebug (mDNS_LoggingEnabled == 0) ? ((void)0) : LogDebug_
169 extern void LogMsg_(const char *format
, ...) IS_A_PRINTF_STYLE_FUNCTION(1,2);
170 extern void LogOperation_(const char *format
, ...) IS_A_PRINTF_STYLE_FUNCTION(1,2);
171 extern void LogSPS_(const char *format
, ...) IS_A_PRINTF_STYLE_FUNCTION(1,2);
172 extern void LogInfo_(const char *format
, ...) IS_A_PRINTF_STYLE_FUNCTION(1,2);
173 extern void LogDebug_(const char *format
, ...) IS_A_PRINTF_STYLE_FUNCTION(1,2);
178 #define debugf debugf_
179 extern void debugf_(const char *format
, ...) IS_A_PRINTF_STYLE_FUNCTION(1,2);
181 #define debugf debug_noop
184 #if MDNS_DEBUGMSGS > 1
185 #define verbosedebugf verbosedebugf_
186 extern void verbosedebugf_(const char *format
, ...) IS_A_PRINTF_STYLE_FUNCTION(1,2);
188 #define verbosedebugf debug_noop
191 extern int mDNS_LoggingEnabled
;
192 extern int mDNS_PacketLoggingEnabled
;
193 extern int mDNS_McastLoggingEnabled
;
194 extern int mDNS_McastTracingEnabled
;
195 extern int mDNS_DebugMode
; // If non-zero, LogMsg() writes to stderr instead of syslog
196 extern const char ProgramName
[];
198 extern void LogMsgWithLevel(mDNSLogCategory_t category
, mDNSLogLevel_t level
, const char *format
, ...) IS_A_PRINTF_STYLE_FUNCTION(3,4);
199 // LogMsgNoIdent needs to be fixed so that it logs without the ident prefix like it used to
200 // (or completely overhauled to use the new "log to a separate file" facility)
201 #define LogMsgNoIdent LogMsg
203 #if APPLE_OSX_mDNSResponder
204 extern void LogFatalError(const char *format
, ...);
206 #define LogFatalError LogMsg
209 #if MDNS_MALLOC_DEBUGGING >= 1
210 extern void *mallocL(const char *msg
, mDNSu32 size
);
211 extern void *callocL(const char *msg
, mDNSu32 size
);
212 extern void freeL(const char *msg
, void *x
);
213 #if APPLE_OSX_mDNSResponder
214 extern void LogMemCorruption(const char *format
, ...);
216 #define LogMemCorruption LogMsg
219 #define mallocL(MSG, SIZE) malloc(SIZE)
220 #define callocL(MSG, SIZE) calloc(1, SIZE)
221 #define freeL(MSG, PTR) free(PTR)
228 #if MDNSRESPONDER_SUPPORTS(APPLE, OS_LOG)
229 /** @brief Write a log message to system's log storage(memory or disk).
231 * On Apple platform, os_log() will be called to log a message.
233 * @param CATEGORY A custom log object previously created by the os_log_create function, and such an object is
234 * used to specify "subsystem" and "category". For mDNSResponder, the subsystem should always
235 * be set to "com.apple.mDNSResponder"; and the category is used for categorization and
236 * filtering of related log messages within the subsystem’s settings. We have 4 categories that
237 * are pre-defined: MDNS_LOG_CATEGORY_DEFAULT, MDNS_LOG_CATEGORY_MDNS, MDNS_LOG_CATEGORY_UDNS,
238 * MDNS_LOG_CATEGORY_SPS. If these categories are not enough, use os_log_create to create more.
240 * @param LEVEL The log level that determines the importance of the message. The levels are, in order of
241 * decreasing importance:
242 * MDNS_LOG_FAULT Fault-level messages are intended for capturing system-level errors
243 * that are critical to the system. They are always saved in the data store.
244 * MDNS_LOG_ERROR Error-level messages are intended for reporting process-level errors
245 * that are unexpected and incorrect during the normal operation. They
246 * are always saved in the data store.
247 * MDNS_LOG_WARNING Warning-level messages are intended for capturing unexpected and
248 * possible incorrect behavior that might be used later to root cause
249 * an error or fault. They are are initially stored in memory buffers
250 * and then moved to a data store.
251 * MDNS_LOG_DEFAULT Default-level messages are intended for reporting things that might
252 * result a failure. They are are initially stored in memory buffers
253 * and then moved to a data store.
254 * MDNS_LOG_INFO Info-level messages are intended for capturing information that may
255 * be helpful, but isn’t essential, for troubleshooting errors. They
256 * are initially stored in memory buffers, but will only be moved into
257 * data store when faults and, optionally, errors occur.
258 * MDNS_LOG_DEBUG Debug-level messages are intended for information that may be useful
259 * during development or while troubleshooting a specific problem, Debug
260 * logging should not be used in shipping software. They are only
261 * captured in memory when debug logging is enabled through a
262 * configuration change.
264 * @param FORMAT A constant string or format string that produces a human-readable log message. The format
265 * string follows the IEEE printf specification, besides the following customized format specifiers:
266 * %{mdnsresponder:domain_name}.*P the pointer to a DNS lable sequence
267 * %{mdnsresponder:ip_addr}.20P the pointer to a mDNSAddr variable
268 * %{network:in_addr}.4P the pointer to a mDNSv4Addr variable
269 * %{network:in6_addr}.16P the pointer to a mDNSv6Addr variable
270 * %{mdnsresponder:mac_addr}.6P the pointer to a 6-byte-length MAC address
272 * @param ... The parameter list that will be formated by the format string. Note that if the customized
273 * format specifiers are used and the data length is not specified in the format string, the
274 * size should be listed before the pointer to the data, for example:
275 * "%{mdnsresponder:domain_name}.*P", (name ? (int)DomainNameLength((const domainname *)name) : 0), <the pointer to a DNS label sequence>
278 #define LogRedact(CATEGORY, LEVEL, FORMAT, ...) os_log_with_type(CATEGORY, LEVEL, FORMAT, ## __VA_ARGS__)
280 #if (MDNS_HAS_VA_ARG_MACROS)
281 #if (MDNS_C99_VA_ARGS)
282 #define LogRedact(CATEGORY, LEVEL, ...) \
283 do { if (mDNS_LoggingEnabled) LogMsgWithLevel(CATEGORY, LEVEL, __VA_ARGS__); } while (0)
284 #elif (MDNS_GNU_VA_ARGS)
285 #define LogRedact(CATEGORY, LEVEL, ARGS...) \
286 do { if (mDNS_LoggingEnabled) LogMsgWithLevel(CATEGORY, LEVEL, ARGS); } while (0)
288 #error "Unknown variadic macros"
291 #define LogRedact (mDNS_LoggingEnabled == 0) ? ((void)0) : LogRedact_
292 extern void LogRedact_(const char *format
, ...) IS_A_PRINTF_STYLE_FUNCTION(1,2);
294 #endif // MDNSRESPONDER_SUPPORTS(APPLE, OS_LOG)
296 // The followings are the customized log specifier defined in os_log. For compatibility, we have to define it when it is
297 // not on the Apple platform, for example, the Posix platform. The keyword "public" or "private" is used to control whether
298 // the content would be redacted when the redaction is turned on: "public" means the content will always be printed;
299 // "private" means the content will be printed as <private> if the redaction is turned on, only when the redaction is
300 // turned off, the content will be printed as what it should be.
302 #if MDNSRESPONDER_SUPPORTS(APPLE, OS_LOG)
303 #define PUB_S "%{public}s"
304 #define PRI_S "%{private}s"
310 #if MDNSRESPONDER_SUPPORTS(APPLE, OS_LOG)
311 #define PUB_DM_NAME "%{public, mdnsresponder:domain_name}.*P"
312 #define PRI_DM_NAME "%{private, mdnsresponder:domain_name}.*P"
313 // When DM_NAME_PARAM is used, the file where the function is defined must include DNSEmbeddedAPI.h
314 #define DM_NAME_PARAM(name) ((name) ? ((int)DomainNameLength((const domainname *)(name))) : 0), (name)
316 #define PUB_DM_NAME "%##s"
317 #define PRI_DM_NAME PUB_DM_NAME
318 #define DM_NAME_PARAM(name) (name)
321 #if MDNSRESPONDER_SUPPORTS(APPLE, OS_LOG)
322 #define PUB_IP_ADDR "%{public, mdnsresponder:ip_addr}.20P"
323 #define PRI_IP_ADDR "%{private, mdnsresponder:ip_addr}.20P"
325 #define PUB_IPv4_ADDR "%{public, network:in_addr}.4P"
326 #define PRI_IPv4_ADDR "%{private, network:in_addr}.4P"
328 #define PUB_IPv6_ADDR "%{public, network:in6_addr}.16P"
329 #define PRI_IPv6_ADDR "%{private, network:in6_addr}.16P"
331 #define PUB_IP_ADDR "%#a"
332 #define PRI_IP_ADDR PUB_IP_ADDR
334 #define PUB_IPv4_ADDR "%.4a"
335 #define PRI_IPv4_ADDR PUB_IPv4_ADDR
337 #define PUB_IPv6_ADDR "%.16a"
338 #define PRI_IPv6_ADDR PUB_IPv6_ADDR
341 #if MDNSRESPONDER_SUPPORTS(APPLE, OS_LOG)
342 #define PUB_MAC_ADDR "%{public, mdnsresponder:mac_addr}.6P"
343 #define PRI_MAC_ADDR "%{private, mdnsresponder:mac_addr}.6P"
345 #define PUB_MAC_ADDR "%.6a"
346 #define PRI_MAC_ADDR PUB_MAC_ADDR
349 extern void LogToFD(int fd
, const char *format
, ...);
351 #endif // __mDNSDebug_h