]> git.saurik.com Git - apple/mdnsresponder.git/blob - ServiceRegistration/log_srp.m
mDNSResponder-1310.80.1.tar.gz
[apple/mdnsresponder.git] / ServiceRegistration / log_srp.m
1 //
2 // log_srp.m
3 // log_srp
4 //
5
6 #import <CoreUtils/CoreUtils.h>
7 #import <Foundation/Foundation.h>
8 #import <os/log_private.h>
9 #import <arpa/inet.h>
10 #import "DNSMessage.h"
11
12 // Attribute string macro
13 #define AStr(str) [[NSAttributedString alloc] initWithString:(str)]
14 #define AStrWithFormat(format, ...) AStr(([[NSString alloc] initWithFormat:format, __VA_ARGS__]))
15
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);
20 };
21
22 static NS_RETURNS_RETAINED NSAttributedString *
23 srp_os_log_copy_formatted_string_ipv6_addr_segment(id value)
24 {
25 #define PREFIX_CLASS_MAX_LENGTH 6 // 6 is for <space>(ULA) or <space>(LUA) or <space>(GUA)
26 NSData *data;
27 const uint8_t * addr_data;
28 NSAttributedString * a_str;
29 char buf[INET6_ADDRSTRLEN + PREFIX_CLASS_MAX_LENGTH];
30 char *delimiter;
31 char *ptr;
32 char *ptr_limit;
33 NSString *ns_str;
34
35 buf[sizeof(buf) - 1] = '\0';
36
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]));
40
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));
46
47 addr_data = data.bytes;
48 delimiter = "";
49 ptr = buf;
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));
56 ptr += result;
57 if ((i + 1) % 2 == 0) {
58 delimiter = ":";
59 } else {
60 delimiter = "";
61 }
62 }
63
64 ns_str = @(buf);
65 a_str = AStr(ns_str != nil ? ns_str : nil);
66 exit:
67 return a_str;
68 }
69
70 static NS_RETURNS_RETAINED NSAttributedString *
71 srp_os_log_copy_formatted_string_domain_name(id value)
72 {
73 NSData *data;
74 NSAttributedString *a_str;
75 char buf[kDNSServiceMaxDomainName];
76 OSStatus ret;
77 NSString *ns_str;
78
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]));
82
83 data = (NSData *)value;
84 // NULL pointer is allowed.
85 require_action_quiet(data.bytes != nil, exit, a_str = AStr(@"<null>"));
86
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));
90
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"));
94
95 ns_str = @(buf);
96 a_str = AStr(ns_str != nil ? ns_str : nil);
97 exit:
98 return a_str;
99 }
100
101 static NS_RETURNS_RETAINED NSAttributedString *
102 srp_os_log_copy_formatted_string_mac_addr(id value)
103 {
104 NSData *data;
105 NSAttributedString *a_str;
106 #define MaxMACAddrStrLen 18 // 17 plus '\0'
107 char buf[MaxMACAddrStrLen];
108 OSStatus ret;
109 NSString *ns_str;
110 const uint8_t *mac_addr = NULL;
111
112 buf[MaxMACAddrStrLen - 1] = '\0';
113
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]));
117
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));
122
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]);
126
127 require_action(ret > 0, exit, a_str = AStr(@"<failed to decode - MAC address conversion failed>"));
128
129 ns_str = @(buf);
130 a_str = AStr(ns_str != nil ? ns_str : nil);
131 exit:
132 return a_str;
133 }
134
135 NS_RETURNS_RETAINED
136 NSAttributedString *
137 OSLogCopyFormattedString(const char *type, id value, __unused os_log_type_info_t info)
138 {
139 NSAttributedString *result_str = nil;
140
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},
145 };
146
147 for (size_t i = 0; i < countof(formatters); i++) {
148 if (strcmp(type, formatters[i].type) != 0) {
149 continue;
150 }
151
152 result_str = formatters[i].function(value);
153 break;
154 }
155
156 return result_str;
157 }