]> git.saurik.com Git - apple/configd.git/blame - EventFactory/SCLogParser.m
configd-1061.141.1.tar.gz
[apple/configd.git] / EventFactory / SCLogParser.m
CommitLineData
afb19109
A
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