]> git.saurik.com Git - apple/configd.git/blob - EventFactory/SCLogParser.m
configd-1109.101.1.tar.gz
[apple/configd.git] / EventFactory / SCLogParser.m
1 /*
2 * Copyright (c) 2018 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 #import <Foundation/Foundation.h>
25 #import <EventFactory/EventFactory.h>
26 #import <arpa/inet.h>
27
28 #import "SCLogParser.h"
29
30 @interface SCLogParser ()
31 @property uint64_t nextEventCounter;
32 @end
33
34 @implementation SCLogParser
35
36 - (instancetype)initWithCategory:(NSString *)category eventParser:(EFLogEventParser *)eventParser
37 {
38 self = [super init];
39 if (self) {
40 _category = category;
41 _eventParser = eventParser;
42 _nextEventCounter = 1;
43 }
44 return self;
45 }
46
47 + (NSMutableDictionary<NSString *, NSArray<NSString *> *> *)interfaceMap
48 {
49 static NSMutableDictionary<NSString *, NSArray<NSString *> *> *_interfaceMap = nil;
50 static dispatch_once_t onceToken;
51 dispatch_once(&onceToken, ^{
52 _interfaceMap = [[NSMutableDictionary alloc] init];
53 });
54 return _interfaceMap;
55 }
56
57 - (NSData *)createSubsystemIdentifier
58 {
59 NSString *identifierString = [[NSString alloc] initWithFormat:@"%@.%llu", _category, _nextEventCounter];
60 _nextEventCounter++;
61 const char *utf8String = identifierString.UTF8String;
62 return [[NSData alloc] initWithBytes:utf8String length:strlen(utf8String)];
63 }
64
65 - (NSArray<NSString *> *)addUniqueString:(NSString *)newString toArray:(NSArray<NSString *> *)array
66 {
67 if (array.count > 0) {
68 NSInteger index = [array indexOfObject:newString];
69 return (index == NSNotFound ? [array arrayByAddingObject:newString] : array);
70 } else {
71 return @[ newString ];
72 }
73 }
74
75 - (NSArray<NSString *> *)addUniqueStrings:(NSArray<NSString *> *)strings toArray:(NSArray<NSString *> *)array
76 {
77 if (array == nil) {
78 return strings;
79 }
80
81 NSMutableArray<NSString *> *uniqueStrings = [[NSMutableArray alloc] init];
82 for (NSString *string in strings) {
83 NSInteger index = [array indexOfObject:string];
84 if (index == NSNotFound) {
85 [uniqueStrings addObject:string];
86 }
87 }
88 if (uniqueStrings.count > 0) {
89 return [array arrayByAddingObjectsFromArray:uniqueStrings];
90 } else {
91 return array;
92 }
93 }
94
95 - (EFNetworkControlPathEvent *)createInterfaceEventWithLogEvent:(EFLogEvent *)logEvent matchResult:(NSTextCheckingResult *)matchResult
96 {
97 EFNetworkControlPathEvent *newEvent = nil;
98 NSString *interfaceName = [logEvent substringForCaptureGroup:@TokenInterfaceName inMatchResult:matchResult];
99 if (interfaceName != nil) {
100 if (SCLogParser.interfaceMap[interfaceName] == nil) {
101 SCLogParser.interfaceMap[interfaceName] = @[];
102 }
103 NSData *identifier = [self createSubsystemIdentifier];
104 newEvent = [[EFNetworkControlPathEvent alloc] initWithLogEvent:logEvent subsystemIdentifier:identifier];
105 newEvent.interfaceBSDName = interfaceName;
106 }
107 return newEvent;
108 }
109
110 - (EFNetworkControlPathEvent *)createInterfaceEventWithLogEvent:(EFLogEvent *)logEvent interfaceName:(NSString *)interfaceName
111 {
112 EFNetworkControlPathEvent *newEvent = nil;
113 if (SCLogParser.interfaceMap[interfaceName] == nil) {
114 SCLogParser.interfaceMap[interfaceName] = @[];
115 }
116 NSData *identifier = [self createSubsystemIdentifier];
117 newEvent = [[EFNetworkControlPathEvent alloc] initWithLogEvent:logEvent subsystemIdentifier:identifier];
118 newEvent.interfaceBSDName = interfaceName;
119 return newEvent;
120 }
121
122 - (void)addAddress:(NSString *)addressString toInterfaceEvent:(EFNetworkControlPathEvent *)event
123 {
124 if (event.interfaceBSDName != nil) {
125 NSArray<NSString *> *addresses = SCLogParser.interfaceMap[event.interfaceBSDName];
126 event.addresses = [self addUniqueString:addressString toArray:addresses];
127 SCLogParser.interfaceMap[event.interfaceBSDName] = event.addresses;
128 }
129 }
130
131 - (BOOL)removeAddress:(NSString *)addressString fromInterfaceEvent:(EFNetworkControlPathEvent *)event
132 {
133 if (event.interfaceBSDName != nil) {
134 NSArray<NSString *> *addresses = SCLogParser.interfaceMap[event.interfaceBSDName];
135 if (addresses.count > 0) {
136 NSPredicate *matchPredicate = [NSPredicate predicateWithBlock:^BOOL(id evaluatedObject, __unused NSDictionary<NSString *,id> *bindings) {
137 NSString *matchString = (NSString *)evaluatedObject;
138 if (matchString != nil) {
139 return ![matchString isEqualToString:addressString];
140 } else {
141 return NO;
142 }
143 }];
144 event.addresses = [addresses filteredArrayUsingPredicate:matchPredicate];
145 SCLogParser.interfaceMap[event.interfaceBSDName] = event.addresses;
146 return YES;
147 }
148 }
149
150 return NO;
151 }
152
153 - (NSString *)substringOfString:(NSString *)matchedString forCaptureGroup:(NSString *)groupName inMatchResult:(NSTextCheckingResult *)result
154 {
155 NSString *substring = nil;
156 NSRange groupRange = [result rangeWithName:groupName];
157 if (!NSEqualRanges(groupRange, NSMakeRange(NSNotFound, 0))) {
158 substring = [matchedString substringWithRange:groupRange];
159 }
160 return substring;
161 }
162
163 - (sa_family_t)getAddressFamilyOfAddress:(NSString *)addressString
164 {
165 sa_family_t af = AF_UNSPEC;
166 struct in6_addr v6addr;
167 struct in_addr v4addr;
168
169 if (inet_pton(AF_INET6, addressString.UTF8String, &v6addr) == 1) {
170 af = AF_INET6;
171 } else if (inet_pton(AF_INET, addressString.UTF8String, &v4addr)) {
172 af = AF_INET;
173 }
174
175 return af;
176 }
177
178 @end