]> git.saurik.com Git - apple/mdnsresponder.git/blob - mDNSCore/mDNSDebug.h
mDNSResponder-1310.40.42.tar.gz
[apple/mdnsresponder.git] / mDNSCore / mDNSDebug.h
1 /*
2 * Copyright (c) 2002-2019 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 * http://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 #ifndef __mDNSDebug_h
18 #define __mDNSDebug_h
19
20 #include "mDNSFeatures.h"
21
22 #if MDNSRESPONDER_SUPPORTS(APPLE, OS_LOG)
23 #include <os/log.h>
24 #endif
25
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.)
32
33 //#undef MDNS_DEBUGMSGS
34 //#define MDNS_DEBUGMSGS 2
35
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
43
44 #if MDNSRESPONDER_SUPPORTS(APPLE, OS_LOG)
45 typedef os_log_t mDNSLogCategory_t;
46
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
54 #else
55 typedef const char * mDNSLogCategory_t;
56 typedef enum
57 {
58 MDNS_LOG_FAULT = 1,
59 MDNS_LOG_ERROR = 2,
60 MDNS_LOG_WARNING = 3,
61 MDNS_LOG_DEFAULT = 4,
62 MDNS_LOG_INFO = 5,
63 MDNS_LOG_DEBUG = 6
64 } mDNSLogLevel_t;
65 #endif
66
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;
73 extern os_log_t mDNSLogCategory_Analytics;
74 extern os_log_t mDNSLogCategory_DNSSEC;
75
76 #define MDNS_LOG_CATEGORY_DEFINITION(NAME) mDNSLogCategory_ ## NAME
77 #else
78 #define MDNS_LOG_CATEGORY_DEFINITION(NAME) # NAME
79 #endif
80
81 #define MDNS_LOG_CATEGORY_DEFAULT MDNS_LOG_CATEGORY_DEFINITION(Default)
82 #define MDNS_LOG_CATEGORY_MDNS MDNS_LOG_CATEGORY_DEFINITION(mDNS)
83 #define MDNS_LOG_CATEGORY_UDNS MDNS_LOG_CATEGORY_DEFINITION(uDNS)
84 #define MDNS_LOG_CATEGORY_SPS MDNS_LOG_CATEGORY_DEFINITION(SPS)
85 #define MDNS_LOG_CATEGORY_XPC MDNS_LOG_CATEGORY_DEFINITION(XPC)
86 #define MDNS_LOG_CATEGORY_ANALYTICS MDNS_LOG_CATEGORY_DEFINITION(Analytics)
87 #define MDNS_LOG_CATEGORY_DNSSEC MDNS_LOG_CATEGORY_DEFINITION(DNSSEC)
88
89 // Set this symbol to 1 to answer remote queries for our Address, and reverse mapping PTR
90 #define ANSWER_REMOTE_HOSTNAME_QUERIES 0
91
92 // Set this symbol to 1 to do extra debug checks on malloc() and free()
93 // Set this symbol to 2 to write a log message for every malloc() and free()
94 // #define MDNS_MALLOC_DEBUGGING 1
95
96 #if (MDNS_MALLOC_DEBUGGING > 0) && defined(WIN32)
97 #error "Malloc debugging does not yet work on Windows"
98 #endif
99
100 //#define ForceAlerts 1
101 //#define LogTimeStamps 1
102
103 // Developer-settings section ends here
104
105 #if MDNS_CHECK_PRINTF_STYLE_FUNCTIONS
106 #define IS_A_PRINTF_STYLE_FUNCTION(F,A) __attribute__ ((format(printf,F,A)))
107 #else
108 #define IS_A_PRINTF_STYLE_FUNCTION(F,A)
109 #endif
110
111 #ifdef __cplusplus
112 extern "C" {
113 #endif
114
115 // Variable argument macro support. Use ANSI C99 __VA_ARGS__ where possible. Otherwise, use the next best thing.
116
117 #if (defined(__GNUC__))
118 #if ((__GNUC__ > 3) || ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 2)))
119 #define MDNS_C99_VA_ARGS 1
120 #define MDNS_GNU_VA_ARGS 0
121 #else
122 #define MDNS_C99_VA_ARGS 0
123 #define MDNS_GNU_VA_ARGS 1
124 #endif
125 #define MDNS_HAS_VA_ARG_MACROS 1
126 #elif (_MSC_VER >= 1400) // Visual Studio 2005 and later
127 #define MDNS_C99_VA_ARGS 1
128 #define MDNS_GNU_VA_ARGS 0
129 #define MDNS_HAS_VA_ARG_MACROS 1
130 #elif (defined(__MWERKS__))
131 #define MDNS_C99_VA_ARGS 1
132 #define MDNS_GNU_VA_ARGS 0
133 #define MDNS_HAS_VA_ARG_MACROS 1
134 #else
135 #define MDNS_C99_VA_ARGS 0
136 #define MDNS_GNU_VA_ARGS 0
137 #define MDNS_HAS_VA_ARG_MACROS 0
138 #endif
139
140 #if (MDNS_HAS_VA_ARG_MACROS)
141 #if (MDNS_C99_VA_ARGS)
142 #define MDNS_LOG_DEFINITION(LEVEL, ...) \
143 do { if (mDNS_LoggingEnabled) LogMsgWithLevel(MDNS_LOG_CATEGORY_DEFAULT, LEVEL, __VA_ARGS__); } while (0)
144
145 #define debug_noop(...) do {} while(0)
146 #define LogMsg(...) LogMsgWithLevel(MDNS_LOG_CATEGORY_DEFAULT, MDNS_LOG_DEFAULT, __VA_ARGS__)
147 #define LogOperation(...) MDNS_LOG_DEFINITION(MDNS_LOG_INFO, __VA_ARGS__)
148 #define LogSPS(...) MDNS_LOG_DEFINITION(MDNS_LOG_INFO, __VA_ARGS__)
149 #define LogInfo(...) MDNS_LOG_DEFINITION(MDNS_LOG_INFO, __VA_ARGS__)
150 #define LogDebug(...) MDNS_LOG_DEFINITION(MDNS_LOG_DEBUG, __VA_ARGS__)
151 #elif (MDNS_GNU_VA_ARGS)
152 #define MDNS_LOG_DEFINITION(LEVEL, ARGS...) \
153 do { if (mDNS_LoggingEnabled) LogMsgWithLevel(MDNS_LOG_CATEGORY_DEFAULT, LEVEL, ARGS); } while (0)
154
155 #define debug_noop(ARGS...) do {} while (0)
156 #define LogMsg(ARGS... ) LogMsgWithLevel(MDNS_LOG_CATEGORY_DEFAULT, MDNS_LOG_DEFAULT, ARGS)
157 #define LogOperation(ARGS...) MDNS_LOG_DEFINITION(MDNS_LOG_INFO, ARGS)
158 #define LogSPS(ARGS...) MDNS_LOG_DEFINITION(MDNS_LOG_INFO, ARGS)
159 #define LogInfo(ARGS...) MDNS_LOG_DEFINITION(MDNS_LOG_INFO, ARGS)
160 #define LogDebug(ARGS...) MDNS_LOG_DEFINITION(MDNS_LOG_DEBUG, ARGS)
161 #else
162 #error "Unknown variadic macros"
163 #endif
164 #else
165 // If your platform does not support variadic macros, you need to define the following variadic functions.
166 // See mDNSShared/mDNSDebug.c for sample implementation
167 #define debug_noop 1 ? (void)0 : (void)
168 #define LogMsg LogMsg_
169 #define LogOperation (mDNS_LoggingEnabled == 0) ? ((void)0) : LogOperation_
170 #define LogSPS (mDNS_LoggingEnabled == 0) ? ((void)0) : LogSPS_
171 #define LogInfo (mDNS_LoggingEnabled == 0) ? ((void)0) : LogInfo_
172 #define LogDebug (mDNS_LoggingEnabled == 0) ? ((void)0) : LogDebug_
173 extern void LogMsg_(const char *format, ...) IS_A_PRINTF_STYLE_FUNCTION(1,2);
174 extern void LogOperation_(const char *format, ...) IS_A_PRINTF_STYLE_FUNCTION(1,2);
175 extern void LogSPS_(const char *format, ...) IS_A_PRINTF_STYLE_FUNCTION(1,2);
176 extern void LogInfo_(const char *format, ...) IS_A_PRINTF_STYLE_FUNCTION(1,2);
177 extern void LogDebug_(const char *format, ...) IS_A_PRINTF_STYLE_FUNCTION(1,2);
178 #endif
179
180
181 #if MDNS_DEBUGMSGS
182 #define debugf debugf_
183 extern void debugf_(const char *format, ...) IS_A_PRINTF_STYLE_FUNCTION(1,2);
184 #else
185 #define debugf debug_noop
186 #endif
187
188 #if MDNS_DEBUGMSGS > 1
189 #define verbosedebugf verbosedebugf_
190 extern void verbosedebugf_(const char *format, ...) IS_A_PRINTF_STYLE_FUNCTION(1,2);
191 #else
192 #define verbosedebugf debug_noop
193 #endif
194
195 extern int mDNS_LoggingEnabled;
196 extern int mDNS_PacketLoggingEnabled;
197 extern int mDNS_McastLoggingEnabled;
198 extern int mDNS_McastTracingEnabled;
199 extern int mDNS_DebugMode; // If non-zero, LogMsg() writes to stderr instead of syslog
200 extern const char ProgramName[];
201
202 extern void LogMsgWithLevel(mDNSLogCategory_t category, mDNSLogLevel_t level, const char *format, ...) IS_A_PRINTF_STYLE_FUNCTION(3,4);
203 // LogMsgNoIdent needs to be fixed so that it logs without the ident prefix like it used to
204 // (or completely overhauled to use the new "log to a separate file" facility)
205 #define LogMsgNoIdent LogMsg
206
207 #if APPLE_OSX_mDNSResponder
208 extern void LogFatalError(const char *format, ...);
209 #else
210 #define LogFatalError LogMsg
211 #endif
212
213 #if MDNS_MALLOC_DEBUGGING >= 1
214 extern void *mallocL(const char *msg, mDNSu32 size);
215 extern void *callocL(const char *msg, mDNSu32 size);
216 extern void freeL(const char *msg, void *x);
217 #if APPLE_OSX_mDNSResponder
218 extern void LogMemCorruption(const char *format, ...);
219 #else
220 #define LogMemCorruption LogMsg
221 #endif
222 #else
223 #define mallocL(MSG, SIZE) malloc(SIZE)
224 #define callocL(MSG, SIZE) calloc(1, SIZE)
225 #define freeL(MSG, PTR) free(PTR)
226 #endif
227
228 #ifdef __cplusplus
229 }
230 #endif
231
232 #if MDNSRESPONDER_SUPPORTS(APPLE, OS_LOG)
233 /** @brief Write a log message to system's log storage(memory or disk).
234 *
235 * On Apple platform, os_log() will be called to log a message.
236 *
237 * @param CATEGORY A custom log object previously created by the os_log_create function, and such an object is
238 * used to specify "subsystem" and "category". For mDNSResponder, the subsystem should always
239 * be set to "com.apple.mDNSResponder"; and the category is used for categorization and
240 * filtering of related log messages within the subsystem’s settings. We have 4 categories that
241 * are pre-defined: MDNS_LOG_CATEGORY_DEFAULT, MDNS_LOG_CATEGORY_MDNS, MDNS_LOG_CATEGORY_UDNS,
242 * MDNS_LOG_CATEGORY_SPS. If these categories are not enough, use os_log_create to create more.
243 *
244 * @param LEVEL The log level that determines the importance of the message. The levels are, in order of
245 * decreasing importance:
246 * MDNS_LOG_FAULT Fault-level messages are intended for capturing system-level errors
247 * that are critical to the system. They are always saved in the data store.
248 * MDNS_LOG_ERROR Error-level messages are intended for reporting process-level errors
249 * that are unexpected and incorrect during the normal operation. They
250 * are always saved in the data store.
251 * MDNS_LOG_WARNING Warning-level messages are intended for capturing unexpected and
252 * possible incorrect behavior that might be used later to root cause
253 * an error or fault. They are are initially stored in memory buffers
254 * and then moved to a data store.
255 * MDNS_LOG_DEFAULT Default-level messages are intended for reporting things that might
256 * result a failure. They are are initially stored in memory buffers
257 * and then moved to a data store.
258 * MDNS_LOG_INFO Info-level messages are intended for capturing information that may
259 * be helpful, but isn’t essential, for troubleshooting errors. They
260 * are initially stored in memory buffers, but will only be moved into
261 * data store when faults and, optionally, errors occur.
262 * MDNS_LOG_DEBUG Debug-level messages are intended for information that may be useful
263 * during development or while troubleshooting a specific problem, Debug
264 * logging should not be used in shipping software. They are only
265 * captured in memory when debug logging is enabled through a
266 * configuration change.
267 *
268 * @param FORMAT A constant string or format string that produces a human-readable log message. The format
269 * string follows the IEEE printf specification, besides the following customized format specifiers:
270 * %{mdnsresponder:domain_name}.*P the pointer to a DNS lable sequence
271 * %{mdnsresponder:ip_addr}.20P the pointer to a mDNSAddr variable
272 * %{network:in_addr}.4P the pointer to a mDNSv4Addr variable
273 * %{network:in6_addr}.16P the pointer to a mDNSv6Addr variable
274 * %{mdnsresponder:mac_addr}.6P the pointer to a 6-byte-length MAC address
275 *
276 * @param ... The parameter list that will be formated by the format string. Note that if the customized
277 * format specifiers are used and the data length is not specified in the format string, the
278 * size should be listed before the pointer to the data, for example:
279 * "%{mdnsresponder:domain_name}.*P", (name ? (int)DomainNameLength((const domainname *)name) : 0), <the pointer to a DNS label sequence>
280 *
281 */
282 #define LogRedact(CATEGORY, LEVEL, FORMAT, ...) os_log_with_type(CATEGORY, LEVEL, FORMAT, ## __VA_ARGS__)
283 #else
284 #if (MDNS_HAS_VA_ARG_MACROS)
285 #if (MDNS_C99_VA_ARGS)
286 #define LogRedact(CATEGORY, LEVEL, ...) \
287 do { if (mDNS_LoggingEnabled) LogMsgWithLevel(CATEGORY, LEVEL, __VA_ARGS__); } while (0)
288 #elif (MDNS_GNU_VA_ARGS)
289 #define LogRedact(CATEGORY, LEVEL, ARGS...) \
290 do { if (mDNS_LoggingEnabled) LogMsgWithLevel(CATEGORY, LEVEL, ARGS); } while (0)
291 #else
292 #error "Unknown variadic macros"
293 #endif
294 #else
295 #define LogRedact (mDNS_LoggingEnabled == 0) ? ((void)0) : LogRedact_
296 extern void LogRedact_(const char *format, ...) IS_A_PRINTF_STYLE_FUNCTION(1,2);
297 #endif
298 #endif // MDNSRESPONDER_SUPPORTS(APPLE, OS_LOG)
299
300 // The followings are the customized log specifier defined in os_log. For compatibility, we have to define it when it is
301 // not on the Apple platform, for example, the Posix platform. The keyword "public" or "private" is used to control whether
302 // the content would be redacted when the redaction is turned on: "public" means the content will always be printed;
303 // "private" means the content will be printed as <mask.hash: '<The hashed string from binary data>'> if the redaction is turned on,
304 // only when the redaction is turned off, the content will be printed as what it should be. Note that the hash performed
305 // to the data is a salted hashing transformation, and the salt is generated randomly on a per-process basis, meaning
306 // that hashes cannot be correlated across processes or devices.
307
308 #if MDNSRESPONDER_SUPPORTS(APPLE, OS_LOG)
309 #define PUB_S "%{public}s"
310 #define PRI_S "%{private, mask.hash}s"
311 #else
312 #define PUB_S "%s"
313 #define PRI_S PUB_S
314 #endif
315
316 #if MDNSRESPONDER_SUPPORTS(APPLE, OS_LOG)
317 #define PUB_DM_NAME "%{public, mdnsresponder:domain_name}.*P"
318 #define PRI_DM_NAME "%{private, mask.hash, mdnsresponder:domain_name}.*P"
319 // When DM_NAME_PARAM is used, the file where the function is defined must include DNSEmbeddedAPI.h
320 #define DM_NAME_PARAM(name) ((name) ? ((int)DomainNameLength((name))) : 0), (name)
321 #else
322 #define PUB_DM_NAME "%##s"
323 #define PRI_DM_NAME PUB_DM_NAME
324 #define DM_NAME_PARAM(name) (name)
325 #endif
326
327 #if MDNSRESPONDER_SUPPORTS(APPLE, OS_LOG)
328 #define PUB_IP_ADDR "%{public, mdnsresponder:ip_addr}.20P"
329 #define PRI_IP_ADDR "%{private, mask.hash, mdnsresponder:ip_addr}.20P"
330
331 #define PUB_IPv4_ADDR "%{public, network:in_addr}.4P"
332 #define PRI_IPv4_ADDR "%{private, mask.hash, network:in_addr}.4P"
333
334 #define PUB_IPv6_ADDR "%{public, network:in6_addr}.16P"
335 #define PRI_IPv6_ADDR "%{private, mask.hash, network:in6_addr}.16P"
336 #else
337 #define PUB_IP_ADDR "%#a"
338 #define PRI_IP_ADDR PUB_IP_ADDR
339
340 #define PUB_IPv4_ADDR "%.4a"
341 #define PRI_IPv4_ADDR PUB_IPv4_ADDR
342
343 #define PUB_IPv6_ADDR "%.16a"
344 #define PRI_IPv6_ADDR PUB_IPv6_ADDR
345 #endif
346
347 #if MDNSRESPONDER_SUPPORTS(APPLE, OS_LOG)
348 #define PUB_MAC_ADDR "%{public, mdnsresponder:mac_addr}.6P"
349 #define PRI_MAC_ADDR "%{private, mask.hash, mdnsresponder:mac_addr}.6P"
350 #else
351 #define PUB_MAC_ADDR "%.6a"
352 #define PRI_MAC_ADDR PUB_MAC_ADDR
353 #endif
354
355 #if MDNSRESPONDER_SUPPORTS(APPLE, OS_LOG)
356 #define PUB_DNSKEY "%{public, mdns:rd.dnskey}.*P"
357 #define PRI_DNSKEY "%{private, mask.hash, mdns:rd.dnskey}.*P"
358 #define DNSKEY_PARAM(rdata, rdata_length) (rdata_length), (rdata)
359 #else
360 #define PUB_DNSKEY "%p"
361 #define PRI_DNSKEY PUB_DNSKEY
362 #define DNSKEY_PARAM(rdata, rdata_length) (rdata)
363 #endif
364
365 #if MDNSRESPONDER_SUPPORTS(APPLE, OS_LOG)
366 #define PUB_DS "%{public, mdns:rd.ds}.*P"
367 #define PRI_DS "%{private, mask.hash, mdns:rd.ds}.*P"
368 #define DS_PARAM(rdata, rdata_length) (rdata_length), (rdata)
369 #else
370 #define PUB_DS "%p"
371 #define PRI_DS PUB_DS
372 #define DS_PARAM(rdata, rdata_length) (rdata)
373 #endif
374
375 #if MDNSRESPONDER_SUPPORTS(APPLE, OS_LOG)
376 #define PUB_NSEC "%{public, mdns:rd.nsec}.*P"
377 #define PRI_NSEC "%{private, mask.hash, mdns:rd.nsec}.*P"
378 #define NSEC_PARAM(rdata, rdata_length) (rdata_length), (rdata)
379 #else
380 #define PUB_NSEC "%p"
381 #define PRI_NSEC PUB_NSEC
382 #define NSEC_PARAM(rdata, rdata_length) (rdata)
383 #endif
384
385 #if MDNSRESPONDER_SUPPORTS(APPLE, OS_LOG)
386 #define PUB_NSEC3 "%{public, mdns:rd.nsec3}.*P"
387 #define PRI_NSEC3 "%{private, mask.hash, mdns:rd.nsec3}.*P"
388 #define NSEC3_PARAM(rdata, rdata_length) (rdata_length), (rdata)
389 #else
390 #define PUB_NSEC3 "%p"
391 #define PRI_NSEC3 PUB_NSEC3
392 #define NSEC3_PARAM(rdata, rdata_length) (rdata)
393 #endif
394
395 #if MDNSRESPONDER_SUPPORTS(APPLE, OS_LOG)
396 #define PUB_RRSIG "%{public, mdns:rd.rrsig}.*P"
397 #define PRI_RRSIG "%{private, mask.hash, mdns:rd.rrsig}.*P"
398 #define RRSIG_PARAM(rdata, rdata_length) (rdata_length), (rdata)
399 #else
400 #define PUB_RRSIG "%p"
401 #define PRI_RRSIG PUB_RRSIG
402 #define RRSIG_PARAM(rdata, rdata_length) (rdata)
403 #endif
404
405 #if MDNSRESPONDER_SUPPORTS(APPLE, OS_LOG)
406 #define PUB_SVCB "%{public, mdns:rd.svcb}.*P"
407 #define PRI_SVCB "%{private, mask.hash, mdns:rd.svcb}.*P"
408 #define SVCB_PARAM(rdata, rdata_length) (rdata_length), (rdata)
409 #else
410 #define PUB_SVCB "%p"
411 #define PRI_SVCB PUB_SVCB
412 #define SVCB_PARAM(rdata, rdata_length) (rdata)
413 #endif
414
415 extern void LogToFD(int fd, const char *format, ...);
416
417 #endif // __mDNSDebug_h