]> git.saurik.com Git - apple/configd.git/blob - EventFactory/EventFactory.m
configd-1109.40.9.tar.gz
[apple/configd.git] / EventFactory / EventFactory.m
1 /*
2 * Copyright (c) 2017-2019 Apple Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
11 * file.
12 *
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23
24 /*
25 * Modification History
26 *
27 * November 15, 2017 Allan Nathanson <ajn@apple.com>
28 * - initial revision
29 */
30
31 #import <os/log.h>
32 #import "EventFactory.h"
33 #import "SCLogParser.h"
34 #import "InterfaceNamerParser.h"
35 #import "IPMonitorParser.h"
36 #import "KernelEventMonitorParser.h"
37 #import "PreferencesMonitorParser.h"
38 #import "StateDumpParser.h"
39 #import "IPConfigurationParser.h"
40 #import "SCDynamicStoreParser.h"
41 #import "SCPreferencesParser.h"
42
43 #pragma mark -
44 #pragma mark Logging
45
46 os_log_t
47 __log_Spectacles(void)
48 {
49 static os_log_t log = NULL;
50
51 if (log == NULL) {
52 log = os_log_create("com.apple.spectacles", "SystemConfiguration");
53 }
54
55 return log;
56 }
57
58 #pragma mark -
59 #pragma mark SystemConfiguratioin Network Event Factory
60
61 typedef NS_ENUM(NSInteger, LogAccumulatingState) {
62 NOT_ACCUMULATING,
63 ACCUMULATING_DNS,
64 ACCUMULATING_NWIv4,
65 ACCUMULATING_NWIv6,
66 };
67
68 @interface EventFactory ()
69 @property NSDictionary<NSString *, SCLogParser *> *parserMap;
70 @property LogAccumulatingState accumulating;
71 @property EFLogEvent *accumulatingEvent;
72 @property NSString *accumulatingEventIdentifierString;
73 @end
74
75 @implementation EventFactory
76
77 - (void)startWithLogSourceAttributes:(__unused NSDictionary<NSString *, NSObject *> *)attributes
78 {
79 NSMutableDictionary<NSString *, SCLogParser *> *newParserMap = [[NSMutableDictionary alloc] init];
80 SCLogParser *parser;
81
82 parser = [[InterfaceNamerParser alloc] init];
83 newParserMap[parser.category] = parser;
84
85 parser = [[IPConfigurationParser alloc] init];
86 newParserMap[parser.category] = parser;
87
88 parser = [[IPMonitorParser alloc] init];
89 newParserMap[parser.category] = parser;
90
91 parser = [[KernelEventMonitorParser alloc] init];
92 newParserMap[parser.category] = parser;
93
94 parser = [[PreferencesMonitorParser alloc] init];
95 newParserMap[parser.category] = parser;
96
97 parser = [[StateDumpParser alloc] init];
98 newParserMap[parser.category] = parser;
99
100 parser = [[SCDynamicStoreParser alloc] init];
101 newParserMap[parser.category] = parser;
102
103 parser = [[SCPreferencesParser alloc] init];
104 newParserMap[parser.category] = parser;
105
106 _parserMap = [[NSDictionary alloc] initWithDictionary:newParserMap];
107
108 _accumulating = NOT_ACCUMULATING;
109 }
110
111 - (NSString *)logEventIdentifierString:(EFLogEvent *)logEvent
112 {
113 NSString *identifierString;
114
115 identifierString = [[NSString alloc] initWithFormat:@"%@[%d]:%@:%@",
116 logEvent.process,
117 logEvent.processIdentifier,
118 logEvent.subsystem,
119 logEvent.category];
120
121 return identifierString;
122 }
123
124 - (void)handleLogEvent:(EFLogEvent *)logEvent completionHandler:(void (^)(NSArray<EFEvent *> * _Nullable))completionHandler
125 {
126 if ([logEvent.eventType isEqualToString:@"stateEvent"]) {
127 logEvent.subsystem = @"com.apple.SystemConfiguration";
128 logEvent.category = @"StateDump";
129 } else if ([logEvent.subsystem isEqualToString:@"com.apple.IPConfiguration"]) {
130 logEvent.category = @"IPConfiguration";
131 }
132
133 if (logEvent.category.length == 0) {
134 specs_log_debug("Skipped message without a category: %@", logEvent.eventMessage);
135 completionHandler(nil);
136 return;
137 }
138
139 if ([logEvent.subsystem isEqualToString:@"com.apple.SystemConfiguration"] &&
140 [logEvent.category isEqualToString:@"IPMonitor"]) {
141 BOOL appendMessage = YES;
142 BOOL done = NO;
143
144 if (_accumulating != NOT_ACCUMULATING) {
145 /*
146 * if we are accumulating a block of log messages
147 */
148 NSString *logEventIdentifierString = [self logEventIdentifierString:logEvent];
149 if ((_accumulating != NOT_ACCUMULATING) &&
150 ![_accumulatingEventIdentifierString isEqualToString:logEventIdentifierString]) {
151 // if the PID changed
152 specs_log_debug("Dropped partial message block: %@", _accumulatingEvent.eventMessage);
153 _accumulating = NOT_ACCUMULATING;
154 _accumulatingEvent = nil;
155 appendMessage = NO;
156 }
157 }
158
159 switch (_accumulating) {
160 case NOT_ACCUMULATING : {
161 if ([logEvent.eventMessage isEqualToString:@"Updating DNS configuration"]) {
162 /*
163 2019-10-10 14:07:32.891719-0400 0x350 Info 0x0 70 0 configd: [com.apple.SystemConfiguration:IPMonitor] Updating DNS configuration
164 2019-10-10 14:07:32.891722-0400 0x350 Info 0x0 70 0 configd: [com.apple.SystemConfiguration:IPMonitor] DNS configuration
165 -->
166 2019-10-10 14:03:17.549361-0400 0x0 State 0x2ed40 70 14 configd: DNS Configuration
167 DNS configuration
168 */
169 _accumulating = ACCUMULATING_DNS;
170 logEvent.eventMessage = @"DNS Configuration";
171 } else if ([logEvent.eventMessage isEqualToString:@"Updating network information"]) {
172 /*
173 2019-10-10 14:07:32.889595-0400 0x350 Info 0x0 70 0 configd: [com.apple.SystemConfiguration:IPMonitor] Updating network information
174 2019-10-10 14:07:32.889596-0400 0x350 Info 0x0 70 0 configd: [com.apple.SystemConfiguration:IPMonitor] Network information (generation 156994061625682 size=1180)
175 -->
176 2019-10-10 14:03:17.549364-0400 0x0 State 0x2ed40 70 14 configd: Network information
177 Network information (generation 55086114928 size=724)
178 */
179 _accumulating = ACCUMULATING_NWIv4;
180 logEvent.eventMessage = @"Network information";
181 }
182
183 if (_accumulating != NOT_ACCUMULATING) {
184 // if we are now accumulating a block of messages
185 _accumulatingEventIdentifierString = [self logEventIdentifierString:logEvent];
186 _accumulatingEvent = logEvent;
187 _accumulatingEvent.subsystem = @"com.apple.SystemConfiguration";
188 _accumulatingEvent.category = @"StateDump";
189 appendMessage = NO;
190 }
191 break;
192 }
193
194 case ACCUMULATING_DNS : {
195 if ([logEvent.eventMessage hasPrefix:@"DNS configuration updated: "]) {
196 done = YES;
197 appendMessage = NO;
198 }
199 break;
200 }
201
202 case ACCUMULATING_NWIv4 : {
203 if ([logEvent.eventMessage isEqualToString:@"IPv6 network interface information"]) {
204 _accumulating = ACCUMULATING_NWIv6;
205 }
206 break;
207 }
208
209 case ACCUMULATING_NWIv6 : {
210 if ([logEvent.eventMessage hasPrefix:@" REACH : "]) {
211 done = YES;
212 }
213 break;
214 }
215 }
216
217 if (appendMessage) {
218 _accumulatingEvent.eventMessage = [NSString stringWithFormat:@"%@\n%@",
219 _accumulatingEvent.eventMessage,
220 logEvent.eventMessage];
221 }
222
223 if (done) {
224 // if we have all we need, pass the [accumulated] event
225 logEvent = _accumulatingEvent;
226 _accumulating = NOT_ACCUMULATING;
227 _accumulatingEvent = nil;
228 } else if (_accumulating != NOT_ACCUMULATING) {
229 // if we are still (or now) accumulating
230 completionHandler(nil);
231 return;
232 }
233 }
234
235 SCLogParser *parser = _parserMap[logEvent.category];
236 if (parser == nil) {
237 specs_log_debug("Skipped message with an unknown category (%@): %@", logEvent.category, logEvent.eventMessage);
238 completionHandler(nil);
239 return;
240 }
241
242 NSArray<EFEvent *> *completeEvents = [parser.eventParser parseLogEventIntoMultipleEvents:logEvent];
243 completionHandler(completeEvents);
244 }
245
246 - (void)finishWithCompletionHandler:(void (^)(NSArray<EFEvent *> * _Nullable))completionHandler
247 {
248 specs_log_notice("Event factory is finishing");
249 completionHandler(nil);
250 }
251
252 @end
253
254