]> git.saurik.com Git - apple/mdnsresponder.git/blob - ServiceRegistration/log_srp.m
mDNSResponder-1310.40.42.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 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) {
56 delimiter = ":";
57 } else {
58 delimiter = "";
59 }
60 }
61
62 ns_str = @(buf);
63 a_str = AStr(ns_str != nil ? ns_str : nil);
64 exit:
65 return a_str;
66 }
67
68 static NS_RETURNS_RETAINED NSAttributedString *
69 srp_os_log_copy_formatted_string_domain_name(id value)
70 {
71 NSData *data;
72 NSAttributedString *a_str;
73 char buf[kDNSServiceMaxDomainName];
74 OSStatus ret;
75 NSString *ns_str;
76
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]));
80
81 data = (NSData *)value;
82 // NULL pointer is allowed.
83 require_action_quiet(data.bytes != nil, exit, a_str = AStr(@"<null>"));
84
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));
88
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"));
92
93 ns_str = @(buf);
94 a_str = AStr(ns_str != nil ? ns_str : nil);
95 exit:
96 return a_str;
97 }
98
99 static NS_RETURNS_RETAINED NSAttributedString *
100 srp_os_log_copy_formatted_string_mac_addr(id value)
101 {
102 NSData *data;
103 NSAttributedString *a_str;
104 #define MaxMACAddrStrLen 18 // 17 plus '\0'
105 char buf[MaxMACAddrStrLen];
106 OSStatus ret;
107 NSString *ns_str;
108 const uint8_t *mac_addr = NULL;
109
110 buf[MaxMACAddrStrLen - 1] = '\0';
111
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]));
115
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));
120
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]);
124
125 require_action(ret > 0, exit, a_str = AStr(@"<failed to decode - MAC address conversion failed>"));
126
127 ns_str = @(buf);
128 a_str = AStr(ns_str != nil ? ns_str : nil);
129 exit:
130 return a_str;
131 }
132
133 NS_RETURNS_RETAINED
134 NSAttributedString *
135 OSLogCopyFormattedString(const char *type, id value, __unused os_log_type_info_t info)
136 {
137 NSAttributedString *result_str = nil;
138
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},
143 };
144
145 for (size_t i = 0; i < countof(formatters); i++) {
146 if (strcmp(type, formatters[i].type) != 0) {
147 continue;
148 }
149
150 result_str = formatters[i].function(value);
151 break;
152 }
153
154 return result_str;
155 }