6 #import <CoreUtils/CoreUtils.h>
7 #import <Foundation/Foundation.h>
8 #import <os/log_private.h>
10 #import "DNSMessage.h"
12 // Attribute string macro
13 #define AStr(str) [[NSAttributedString alloc] initWithString:(str)]
14 #define AStrWithFormat(format, ...) AStr(([[NSString alloc] initWithFormat:format, __VA_ARGS__]))
16 typedef struct srp_os_log_formatter srp_os_log_formatter_t;
17 struct srp_os_log_formatter {
18 const char * const type;
19 NS_RETURNS_RETAINED NSAttributedString *(*function)(id);
22 static NS_RETURNS_RETAINED NSAttributedString *
23 srp_os_log_copy_formatted_string_ipv6_addr_segment(id value)
25 #define PREFIX_CLASS_MAX_LENGTH 6 // 6 is for <space>(ULA) or <space>(LUA) or <space>(GUA)
27 const uint8_t * addr_data;
28 NSAttributedString * a_str;
29 char buf[INET6_ADDRSTRLEN + PREFIX_CLASS_MAX_LENGTH];
35 buf[sizeof(buf) - 1] = '\0';
37 // The passing data should be NSData type.
38 require_action([(NSObject *)value isKindOfClass:[NSData class]], exit,
39 a_str = AStrWithFormat(@"<failed to decode - invalid data type: %@>", [(NSObject *)value description]));
41 data = (NSData *)value;
42 // The passing data must have valid length.
43 #define IPv6_ADDR_SIZE 16
44 require_action(data.bytes != nil && data.length > 0 && data.length <= IPv6_ADDR_SIZE, exit,
45 a_str = AStrWithFormat(@"<failed to decode - NIL or invalid data length: %lu>", (unsigned long)data.length));
47 addr_data = data.bytes;
50 ptr_limit = buf + sizeof(buf);
51 for (size_t i = 0; i < data.length; i++) {
52 size_t remaining = (size_t)(ptr_limit - ptr);
53 int result = snprintf(ptr, remaining, "%s%02x", delimiter, addr_data[i]);
54 require_action(result > 0 && result < remaining, exit,
55 a_str = AStrWithFormat(@"<failed to decode - snprintf: result: %ld remain: %lu>", i, remaining));
57 if ((i + 1) % 2 == 0) {
65 a_str = AStr(ns_str != nil ? ns_str : nil);
70 static NS_RETURNS_RETAINED NSAttributedString *
71 srp_os_log_copy_formatted_string_domain_name(id value)
74 NSAttributedString *a_str;
75 char buf[kDNSServiceMaxDomainName];
79 // The passing data should be NSData type.
80 require_action([(NSObject *)value isKindOfClass:[NSData class]], exit,
81 a_str = AStrWithFormat(@"<failed to decode - invalid data type: %@>", [(NSObject *)value description]));
83 data = (NSData *)value;
84 // NULL pointer is allowed.
85 require_action_quiet(data.bytes != nil, exit, a_str = AStr(@"<null>"));
87 // The passing data must have valid length.
88 require_action(data.length > 0 && data.length <= kDomainNameLengthMax, exit,
89 a_str = AStrWithFormat(@"<failed to decode - NIL or invalid data length: %lu>", (unsigned long)data.length));
91 buf[kDNSServiceMaxDomainName - 1] = '\0';
92 ret = DomainNameToString((const uint8_t *)data.bytes, ((const uint8_t *) data.bytes) + data.length, buf, NULL);
93 require_action(ret == kNoErr, exit, a_str = AStr(@"Malformed Domain Name"));
96 a_str = AStr(ns_str != nil ? ns_str : nil);
101 static NS_RETURNS_RETAINED NSAttributedString *
102 srp_os_log_copy_formatted_string_mac_addr(id value)
105 NSAttributedString *a_str;
106 #define MaxMACAddrStrLen 18 // 17 plus '\0'
107 char buf[MaxMACAddrStrLen];
110 const uint8_t *mac_addr = NULL;
112 buf[MaxMACAddrStrLen - 1] = '\0';
114 // The passing data should be NSData type.
115 require_action([(NSObject *)value isKindOfClass:[NSData class]], exit,
116 a_str = AStrWithFormat(@"<failed to decode - invalid data type: %@>", [(NSObject *)value description]));
118 data = (NSData *)value;
119 #define MACAddressLen 6
120 require_action(data.bytes != nil && data.length == MACAddressLen, exit,
121 a_str = AStrWithFormat(@"<failed to decode - NIL or invalid data length: %lu>", (unsigned long)data.length));
123 mac_addr = (const uint8_t *)data.bytes;
124 ret = snprintf(buf, sizeof(buf), "%02x:%02x:%02x:%02x:%02x:%02x",
125 mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5]);
127 require_action(ret > 0, exit, a_str = AStr(@"<failed to decode - MAC address conversion failed>"));
130 a_str = AStr(ns_str != nil ? ns_str : nil);
137 OSLogCopyFormattedString(const char *type, id value, __unused os_log_type_info_t info)
139 NSAttributedString *result_str = nil;
141 static const srp_os_log_formatter_t formatters[] = {
142 {.type = "in6_addr_segment", .function = srp_os_log_copy_formatted_string_ipv6_addr_segment},
143 {.type = "domain_name", .function = srp_os_log_copy_formatted_string_domain_name},
144 {.type = "mac_addr", .function = srp_os_log_copy_formatted_string_mac_addr},
147 for (size_t i = 0; i < countof(formatters); i++) {
148 if (strcmp(type, formatters[i].type) != 0) {
152 result_str = formatters[i].function(value);