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 require_action((size_t)(ptr_limit - ptr) > strlen(delimiter) + 2, exit,
53 a_str = AStrWithFormat(@"<failed to decode - buffer space not enough: i: %lu>", i));
54 ptr += snprintf(ptr, ptr_limit - ptr, "%s%02x", delimiter, addr_data[i]);
55 if ((i + 1) % 2 == 0) {
63 a_str = AStr(ns_str != nil ? ns_str : nil);
68 static NS_RETURNS_RETAINED NSAttributedString *
69 srp_os_log_copy_formatted_string_domain_name(id value)
72 NSAttributedString *a_str;
73 char buf[kDNSServiceMaxDomainName];
77 // The passing data should be NSData type.
78 require_action([(NSObject *)value isKindOfClass:[NSData class]], exit,
79 a_str = AStrWithFormat(@"<failed to decode - invalid data type: %@>", [(NSObject *)value description]));
81 data = (NSData *)value;
82 // NULL pointer is allowed.
83 require_action_quiet(data.bytes != nil, exit, a_str = AStr(@"<null>"));
85 // The passing data must have valid length.
86 require_action(data.length > 0 && data.length <= kDomainNameLengthMax, exit,
87 a_str = AStrWithFormat(@"<failed to decode - NIL or invalid data length: %lu>", (unsigned long)data.length));
89 buf[kDNSServiceMaxDomainName - 1] = '\0';
90 ret = DomainNameToString((const uint8_t *)data.bytes, ((const uint8_t *) data.bytes) + data.length, buf, NULL);
91 require_action(ret == kNoErr, exit, a_str = AStr(@"Malformed Domain Name"));
94 a_str = AStr(ns_str != nil ? ns_str : nil);
99 static NS_RETURNS_RETAINED NSAttributedString *
100 srp_os_log_copy_formatted_string_mac_addr(id value)
103 NSAttributedString *a_str;
104 #define MaxMACAddrStrLen 18 // 17 plus '\0'
105 char buf[MaxMACAddrStrLen];
108 const uint8_t *mac_addr = NULL;
110 buf[MaxMACAddrStrLen - 1] = '\0';
112 // The passing data should be NSData type.
113 require_action([(NSObject *)value isKindOfClass:[NSData class]], exit,
114 a_str = AStrWithFormat(@"<failed to decode - invalid data type: %@>", [(NSObject *)value description]));
116 data = (NSData *)value;
117 #define MACAddressLen 6
118 require_action(data.bytes != nil && data.length == MACAddressLen, exit,
119 a_str = AStrWithFormat(@"<failed to decode - NIL or invalid data length: %lu>", (unsigned long)data.length));
121 mac_addr = (const uint8_t *)data.bytes;
122 ret = snprintf(buf, sizeof(buf), "%02x:%02x:%02x:%02x:%02x:%02x",
123 mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5]);
125 require_action(ret > 0, exit, a_str = AStr(@"<failed to decode - MAC address conversion failed>"));
128 a_str = AStr(ns_str != nil ? ns_str : nil);
135 OSLogCopyFormattedString(const char *type, id value, __unused os_log_type_info_t info)
137 NSAttributedString *result_str = nil;
139 static const srp_os_log_formatter_t formatters[] = {
140 {.type = "in6_addr_segment", .function = srp_os_log_copy_formatted_string_ipv6_addr_segment},
141 {.type = "domain_name", .function = srp_os_log_copy_formatted_string_domain_name},
142 {.type = "mac_addr", .function = srp_os_log_copy_formatted_string_mac_addr},
145 for (size_t i = 0; i < countof(formatters); i++) {
146 if (strcmp(type, formatters[i].type) != 0) {
150 result_str = formatters[i].function(value);